Skip to content

Commit

Permalink
scoring
Browse files Browse the repository at this point in the history
  • Loading branch information
arpruss committed Jul 8, 2016
1 parent d17ee20 commit 20e845c
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 149 deletions.
334 changes: 193 additions & 141 deletions python2-scripts/mcpipy/minetris.py
Original file line number Diff line number Diff line change
@@ -1,190 +1,242 @@
#
# requires Windows and pywin32
# Copyright (c) 2016 Alexander Pruss. MIT License.
#
from mc import *
from time import sleep,time
from random import randint
from text import drawText
from fonts import FONTS
import win32con,win32api

HEIGHT = 22
WIDTH = 9
BORDER = WOOL_BLACK
BACKGROUND = STAINED_GLASS_BLACK

DELAYS = ( 0.5, 0.45, 0.4, 0.35, 0.3, 0.25, 0.2, 0.15, 0.1)

PIECES = ( (('XXXX',), ('.X','.X','.X','.X')),
(('XX','XX'),),
(('XXX', '..X'), ('.X', '.X', 'XX'), ('X','XXX'), ('XX', 'X', 'X')),
(('XXX', 'X'), ('XX', '.X', '.X'), ('..X', 'XXX'), ('X.', 'X.', 'XX')),
(('XX', '.XX'), ('.X','XX', 'X.')),
(('.XX', 'XX'), ('X.', 'XX', '.X')) )
(('XX','XX'),),
(('XXX', '..X'), ('.X', '.X', 'XX'), ('X','XXX'), ('XX', 'X', 'X')),
(('XXX', 'X'), ('XX', '.X', '.X'), ('..X', 'XXX'), ('X.', 'X.', 'XX')),
(('XX', '.XX'), ('.X','XX', 'X.')),
(('.XX', 'XX'), ('X.', 'XX', '.X')) )

def drawBoard():
mc.setBlocks(left-1, bottom-1, plane, left+WIDTH, bottom-1, plane, BORDER)
mc.setBlocks(left-1, bottom+HEIGHT, plane, left+WIDTH, bottom+HEIGHT, plane, BORDER)
mc.setBlocks(left-1, bottom, plane, left, bottom+HEIGHT-1, plane, BORDER)
mc.setBlocks(left+WIDTH, bottom, plane, left+WIDTH, bottom+HEIGHT-1, plane, BORDER)
mc.setBlocks(left-1, bottom-1, plane-1, left+WIDTH, bottom+HEIGHT, plane-1, BACKGROUND)
mc.setBlocks(left, bottom, plane, left+WIDTH-1, bottom+HEIGHT-1, plane, AIR)
mc.setBlocks(left-1, bottom-1, plane, left+WIDTH, bottom-1, plane, BORDER)
mc.setBlocks(left-1, bottom+HEIGHT, plane, left+WIDTH, bottom+HEIGHT, plane, BORDER)
mc.setBlocks(left-1, bottom, plane, left, bottom+HEIGHT-1, plane, BORDER)
mc.setBlocks(left+WIDTH, bottom, plane, left+WIDTH, bottom+HEIGHT-1, plane, BORDER)
mc.setBlocks(left-1, bottom-1, plane-1, left+WIDTH, bottom+HEIGHT, plane-1, BACKGROUND)
mc.setBlocks(left, bottom, plane, left+WIDTH-1, bottom+HEIGHT-1, plane, AIR)
def pieceWidth(piece):
return max((len(a) for a in piece[orientation]))
return max((len(a) for a in piece))
def enumeratePiece(x, y, piece):
for row in range(len(piece)):
for col in range(len(piece[row])):
if piece[row][col] == 'X':
yield (x+col,y-row)

for row in range(len(piece)):
if y-row < HEIGHT:
for col in range(len(piece[row])):
if piece[row][col] == 'X':
yield (x+col,y-row)

def movePiece(oldX, oldY, oldPiece, x, y, piece, color):
new = set(enumeratePiece(x, y, piece))
if oldPiece:
old = set(enumeratePiece(oldX, oldY, oldPiece))

for (x,y) in old-new:
mc.setBlock(x+left, y+bottom, plane, AIR)

new = new - old

for (x,y) in new:
mc.setBlock(x+left, y+bottom, plane, color)

def erasePiece(buffer, x, y, piece):
for (xx,yy) in enumeratePiece(x,y, piece):
buffer[(left+xx,bottom+yy)] = AIR
for (xx,yy) in enumeratePiece(x,y, piece):
buffer[(left+xx,bottom+yy)] = AIR

def drawPiece(buffer, x, y, piece, color):
for (xx,yy) in enumeratePiece(x,y, piece):
if (left+xx,bottom+yy) in buffer and buffer[(left+xx,bottom+yy)] == AIR:
del buffer[(left+xx,bottom+yy)]
else:
buffer[(left+xx,bottom+yy)] = color
for (xx,yy) in enumeratePiece(x,y, piece):
if (left+xx,bottom+yy) in buffer and buffer[(left+xx,bottom+yy)] == AIR:
del buffer[(left+xx,bottom+yy)]
else:
buffer[(left+xx,bottom+yy)] = color
def drawBuffer(buffer):
for x,y in buffer:
mc.setBlock(x,y,plane,buffer[(x,y)])
for x,y in buffer:
mc.setBlock(x,y,plane,buffer[(x,y)])

def placePiece():
global pieceNum, color, family, orientation, x, y, fall, descendDelay
pieceNum = randint(0, len(PIECES)-1)
color = Block(WOOL.id, (pieceNum+1) % 16)
family = PIECES[pieceNum]
orientation = 0
x = WIDTH // 2 - pieceWidth(family[orientation])
y = HEIGHT - 1
descendDelay = currentDescendDelay
fall = False

global pieceNum, color, family, orientation, x, y, fall, descendDelay
pieceNum = randint(0, len(PIECES)-1)
family = PIECES[pieceNum]
color = Block(WOOL.id, (pieceNum+1) % 16)
orientation = randint(0, len(family)-1)
piece = family[orientation]
x = WIDTH // 2 - pieceWidth(piece)
y = HEIGHT + len(piece) - 2
descendDelay = currentDescendDelay
fall = False

def fit(x, y, piece):
for (xx,yy) in enumeratePiece(x, y, piece):
if yy >= HEIGHT or yy < 0 or xx >= WIDTH or xx < 0 or board[xx][yy] is not None:
return False
return True
for (xx,yy) in enumeratePiece(x, y, piece):
if yy < 0 or xx >= WIDTH or xx < 0 or board[xx][yy] is not None:
return False
return True
def descend():
global descendTimer
if descendTimer + descendDelay <= time():
descendTimer += descendDelay
return True
return False
global descendTimer
if descendTimer + descendDelay <= time():
descendTimer += descendDelay
return True
return False
def moveDown():
return (win32api.GetAsyncKeyState(win32con.VK_DOWN)&1)
return (win32api.GetAsyncKeyState(win32con.VK_DOWN)&1)
def moveLeft():
return (win32api.GetAsyncKeyState(win32con.VK_LEFT)&1)
return (win32api.GetAsyncKeyState(win32con.VK_LEFT)&1)
def moveRight():
return (win32api.GetAsyncKeyState(win32con.VK_RIGHT)&1)
return (win32api.GetAsyncKeyState(win32con.VK_RIGHT)&1)

def rotateLeft():
return (win32api.GetAsyncKeyState(win32con.VK_PRIOR)&1)
return (win32api.GetAsyncKeyState(win32con.VK_PRIOR)&1)
def rotateRight():
return (win32api.GetAsyncKeyState(win32con.VK_NEXT)&1) or (win32api.GetAsyncKeyState(win32con.VK_UP)&1)

return ((win32api.GetAsyncKeyState(win32con.VK_NEXT)&1) or
(win32api.GetAsyncKeyState(win32con.VK_UP)&1))

def addPiece(x, y, piece, color):
for (xx,yy) in enumeratePiece(x, y, piece):
board[xx][yy] = color
while True:
foundRow = False
for y in range(HEIGHT):
full = True
for x in range(WIDTH):
if board[x][y] is None:
full = False
break
if full:
foundRow = True
for y2 in range(y, HEIGHT-1):
for x in range(WIDTH):
b = board[x][y2+1]
board[x][y2] = b
mc.setBlock(left+x,bottom+y2,plane,b if b is not None else AIR)
for x in range(WIDTH):
board[x][HEIGHT-1] = None
mc.setBlock(left+x,bottom+HEIGHT-1,plane,AIR)

if not foundRow:
break
global score,level,totalDropped

for (xx,yy) in enumeratePiece(x, y, piece):
board[xx][yy] = color

dropCount = 0
while True:
foundRow = False
for y in range(HEIGHT):
full = True
for x in range(WIDTH):
if board[x][y] is None:
full = False
break
if full:
dropCount += 1
foundRow = True
for y2 in range(y, HEIGHT-1):
for x in range(WIDTH):
b = board[x][y2+1]
board[x][y2] = b
mc.setBlock(left+x,bottom+y2,plane,b if b is not None else AIR)
for x in range(WIDTH):
board[x][HEIGHT-1] = None
mc.setBlock(left+x,bottom+HEIGHT-1,plane,AIR)

if not foundRow:
break

if dropCount:
score += 2**(dropCount-1)
totalDropped += dropCount
level = 1 + totalDropped // 8
if level > 9:
level = 9
updateScoreAndLevel()

def updateText(buffer,x,y,text):
newBuffer = {}
drawText(mc, FONTS['metrix7pt'],
Vec3(x,y,plane),
Vec3(1,0,0), Vec3(0,1,0),
text, SEA_LANTERN, background=None, buffer=newBuffer)
for pos in buffer:
if pos not in newBuffer:
mc.setBlock(pos, AIR)
for pos in newBuffer:
if pos not in buffer:
mc.setBlock(pos, SEA_LANTERN)
return newBuffer

def updateScoreAndLevel():
global scoreBuffer, levelBuffer, currentDescendDelay
scoreBuffer = updateText(scoreBuffer,left+WIDTH+2,bottom+HEIGHT-10,str(score))
levelBuffer = updateText(levelBuffer,left-7,bottom+HEIGHT-10,str(level))
currentDescendDelay = DELAYS[level-1]

mc = Minecraft()

playerPos = mc.player.getTilePos()
mc.player.setRotation(180)
mc.player.setPitch(-30)
mc.player.setTilePos(playerPos.x, playerPos.y, playerPos.z + 10)
mc.player.setPitch(-26)
mc.player.setTilePos(playerPos.x, playerPos.y, playerPos.z + 13)
left = playerPos.x - WIDTH // 2
plane = playerPos.z
bottom = playerPos.y + 1
board = [[None for i in range(HEIGHT)] for j in range(WIDTH)]
currentDescendDelay = 0.5

drawBoard()
score = 0
level = 1
totalDropped = 0
scoreBuffer = {}
levelBuffer = {}
updateScoreAndLevel()

newPiece = True

while True:
if newPiece:
placePiece()
oldPiece = None
if not fit(x, y, family[orientation]):
mc.postToChat("Doesn't fit: End of game")
print "no fit"
break
draw = True
newPiece = False
descendTimer = time()
else:
oldPiece = family[orientation]
draw = False
oldX = x
oldY = y

if not fall:
if moveLeft() and fit(x-1, y, family[orientation]):
x -= 1
draw = True

if moveRight() and fit(x+1, y, family[orientation]):
x += 1
draw = True

if rotateLeft() and fit(x, y, family[(orientation-1)%len(family)]):
orientation = (orientation-1)%len(family)
draw = True

if rotateRight() and fit(x, y, family[(orientation+1)%len(family)]):
orientation = (orientation+1)%len(family)
draw = True

if moveDown():
fall = True
descendDelay = 0.05

if descend():
if not fit(x, y-1, family[orientation]):
addPiece(x, y, family[orientation], color)
newPiece = True
else:
draw = True
y -= 1

if draw:
buffer = {}
if oldPiece:
erasePiece(buffer, oldX, oldY, oldPiece)
drawPiece(buffer, x, y, family[orientation], color)
drawBuffer(buffer)

sleep(0.1)

print "done"
if newPiece:
placePiece()
oldPiece = None
if not fit(x, y, family[orientation]):
mc.postToChat("Doesn't fit: End of game")
break
draw = True
newPiece = False
descendTimer = time()
else:
oldPiece = family[orientation]
draw = False
oldX = x
oldY = y

if not fall:
if moveLeft() and fit(x-1, y, family[orientation]):
x -= 1
draw = True

if moveRight() and fit(x+1, y, family[orientation]):
x += 1
draw = True

if rotateLeft() and fit(x, y, family[(orientation-1)%len(family)]):
orientation = (orientation-1)%len(family)
draw = True

if rotateRight() and fit(x, y, family[(orientation+1)%len(family)]):
orientation = (orientation+1)%len(family)
draw = True

if moveDown():
fall = True
descendDelay = 0.05

if descend():
if not fit(x, y-1, family[orientation]):
addPiece(x, y, family[orientation], color)
newPiece = True
else:
draw = True
y -= 1

if draw:
movePiece(oldX, oldY, oldPiece, x, y, family[orientation], color)

sleep(0.05)

Loading

0 comments on commit 20e845c

Please sign in to comment.