Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F10361490
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/support/arcanoid/arcanoid.py b/support/arcanoid/arcanoid.py
index 55d191a7..6d99d5e0 100755
--- a/support/arcanoid/arcanoid.py
+++ b/support/arcanoid/arcanoid.py
@@ -1,230 +1,235 @@
#!/usr/bin/env python3
import sys
import time
import select
import curses
from curses import wrapper
entities = []
grid = []
class Wall:
def collide(self, ball):
return False
class Block:
killed = 0
total = 0
def __init__(self, x, y, w, h, c):
self.x = int(round(x))
self.y = int(round(y))
self.w = int(round(w))
self.h = int(round(h))
self.fmt = curses.A_BOLD | curses.color_pair(c)
self.alive = True
for i in range(self.x, self.x + self.w):
for j in range(self.y, self.y + self.h):
grid[j + 1][i + 1] = self
Block.total += 1
def collide(self, ball):
self.alive = False
for i in range(self.x, self.x + self.w):
for j in range(self.y, self.y + self.h):
grid[j + 1][i + 1] = None
Block.killed += 1
return False
def tick(self, win):
if self.alive:
for i in range(self.x, self.x + self.w):
for j in range(self.y, self.y + self.h):
win.addch(j, i, curses.ACS_BLOCK, self.fmt)
return self.alive
class Ball:
alive = False
killed = 0
def __init__(self, x, y, vx, vy):
self.x = int(round(x))
self.y = int(round(y))
self.vx = vx
self.vy = vy
Ball.alive = True
def collide(self, ball):
return True
def encounter(self, dx, dy):
dx = int(round(dx))
dy = int(round(dy))
ent = grid[self.y + dy + 1][self.x + dx + 1]
if ent and not ent.collide(self):
self.vx -= 2 * dx
self.vy -= 2 * dy
return ent
def tick(self, win):
while self.y < ship.y:
if self.encounter((self.vx + self.vy) / 2, (self.vy - self.vx) / 2):
continue
if self.encounter((self.vx - self.vy) / 2, (self.vy + self.vx) / 2):
continue
if self.encounter(self.vx, self.vy):
continue
break
self.x += self.vx
self.y += self.vy
try:
win.addch(self.y, self.x, 'O')
except curses.error:
Ball.alive = False
Ball.killed += 1
return Ball.alive
class Ship:
def __init__(self, x, y):
self.x = int(round(x))
self.y = int(round(y))
self.hw = 10
self.v = 4
self.last = 1
self.update()
def update(self):
grid[self.y + 1] = (
[ None ] * (self.x - self.hw + 1) +
[ self ] * (self.hw * 2 + 1) +
[ None ] * (width - self.x - self.hw)
)
def collide(self, ball):
ball.vy = -1
if ball.x > self.x + self.hw / 2:
ball.vx = 1
elif ball.x < self.x - self.hw / 2:
ball.vx = -1
return True
def shift(self, i):
self.last = i
self.x += self.v * i
if self.x - self.hw < 0:
self.x = self.hw
elif self.x + self.hw >= width:
self.x = width - self.hw - 1
self.update()
def spawn(self):
if not Ball.alive:
entities.append(Ball(self.x, self.y - 1, self.last, -1))
def tick(self, win):
if not Ball.alive:
win.addch(self.y - 1, self.x, 'O')
win.addch(self.y, self.x - self.hw, curses.ACS_LTEE)
for i in range(-self.hw + 1, self.hw):
win.addch(curses.ACS_HLINE)
win.addch(curses.ACS_RTEE)
return True
class PowerOverwhelmingException(Exception):
pass
def main(stdscr):
global height, width, ship
for i in range(1, 8):
curses.init_pair(i, i, 0)
curses.curs_set(0)
curses.raw()
height, width = stdscr.getmaxyx()
if height < 15 or width < 32:
raise PowerOverwhelmingException(
'Your computer is not powerful enough to run "arc anoid". '
'It must support at least 32 columns and 15 rows of next-gen '
'full-color 3D graphics.')
status = curses.newwin(1, width, 0, 0)
height -= 1
game = curses.newwin(height, width, 1, 0)
game.nodelay(1)
game.keypad(1)
grid[:] = [ [ None for x in range(width + 2) ] for y in range(height + 2) ]
wall = Wall()
for x in range(width + 2):
grid[0][x] = wall
for y in range(height + 2):
grid[y][0] = grid[y][-1] = wall
ship = Ship(width / 2, height - 5)
entities.append(ship)
colors = [ 1, 3, 2, 6, 4, 5 ]
h = height / 10
for x in range(1, int(width / 7) - 1):
for y in range(1, 7):
entities.append(Block(x * 7,
y * h + x / 2 % 2,
7,
h,
colors[y - 1]))
while True:
while select.select([ sys.stdin ], [], [], 0)[0]:
key = game.getch()
if key == curses.KEY_LEFT or key == ord('a') or key == ord('A'):
ship.shift(-1)
elif key == curses.KEY_RIGHT or key == ord('d') or key == ord('D'):
ship.shift(1)
elif key == ord(' '):
ship.spawn()
elif key == 0x1b or key == 3 or key == ord('q') or key == ord('Q'):
return
game.resize(height, width)
game.erase()
entities[:] = [ ent for ent in entities if ent.tick(game) ]
status.hline(0, 0, curses.ACS_HLINE, width)
status.addch(0, 2, curses.ACS_RTEE)
status.addstr(' SCORE: ', curses.A_BOLD | curses.color_pair(4))
status.addstr('%s/%s ' % (Block.killed, Block.total), curses.A_BOLD)
status.addch(curses.ACS_VLINE)
status.addstr(' DEATHS: ', curses.A_BOLD | curses.color_pair(4))
# See T8693. At the minimum display size, we only have room to render
# two characters for the death count, so just display "99" if the
# player has more than 99 deaths.
display_deaths = Ball.killed
if (display_deaths > 99):
display_deaths = 99
status.addstr('%s ' % display_deaths, curses.A_BOLD)
status.addch(curses.ACS_LTEE)
if Block.killed == Block.total:
message = ' A WINNER IS YOU!! '
i = int(time.time() / 0.8)
for x in range(width):
for y in range(6):
- game.addch(height / 2 + y - 3 + (x / 8 + i) % 2, x,
- curses.ACS_BLOCK,
- curses.A_BOLD | curses.color_pair(colors[y]))
- game.addstr(height / 2, (width - len(message)) / 2, message,
- curses.A_BOLD | curses.color_pair(7))
+ game.addch(
+ int(height / 2 + y - 3 + (x / 8 + i) % 2),
+ x,
+ curses.ACS_BLOCK,
+ curses.A_BOLD | curses.color_pair(colors[y]))
+ game.addstr(
+ int(height / 2),
+ int((width - len(message)) / 2),
+ message,
+ curses.A_BOLD | curses.color_pair(7))
game.refresh()
status.refresh()
time.sleep(0.05)
try:
curses.wrapper(main)
print ('You destroyed %s blocks out of %s with %s deaths.' %
(Block.killed, Block.total, Ball.killed))
except PowerOverwhelmingException as e:
print (e)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 8, 14:04 (6 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1034649
Default Alt Text
(7 KB)
Attached To
Mode
R118 Arcanist - fork
Attached
Detach File
Event Timeline
Log In to Comment