Committing my old Tak project to Forgejo

This commit is contained in:
Awstin 2024-08-09 16:50:29 -04:00
parent 747119e1b8
commit 4869298c0c
22 changed files with 12012 additions and 2 deletions

BIN
2D pieces/capstone-dark.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
2D pieces/capstone-light.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

5511
2D pieces/darkblocks.ai Executable file

File diff suppressed because it is too large Load diff

BIN
2D pieces/flat-dark.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
2D pieces/flat-light.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

5583
2D pieces/lightblock.ai Executable file

File diff suppressed because it is too large Load diff

BIN
2D pieces/wall-dark.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
2D pieces/wall-light.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

73
Actions.py Executable file
View file

@ -0,0 +1,73 @@
def piecesLeft(board, val):
used = board.countTotalPieces()
if val > 0:
if val > 2 and used[3] >= board.capstones:
return False
elif used[1] + used[2] >= board.pieces:
return False
else:
if abs(val) > 2 and used[-3] >= board.capstones:
return False
elif used[-1] + used[-2] >= board.pieces:
return False
return True
def place(board, loc, type):
if not piecesLeft(board, type):
raise ValueError('No more of those pieces left')
elif abs(type) > 3 or type == 0:
raise ValueError('Not a valid piece')
elif board.isEmpty(loc):
board.getLocation(loc)[-1] = type
else:
raise ValueError('This location has pieces you cant place here')
def getPieces(board, loc, num):
hand = []
for i in range(num):
hand.append(board.getLocation(loc).pop())
if board.countStack(loc) == 0:
board.getLocation(loc).append(0)
return hand
def pickup(board, start, dropArray):
number = sum(dropArray)
if number <= board.countStack(start):
return getPieces(board, start, number)
else:
raise ValueError("You can't pick up more pieces than are in the space")
def getDirection(start, end):
if start[0] == end[0]:
return 0, (end[1] - start[1])//abs(end[1] - start[1])
elif start[1] == end[1]:
return (end[0] - start[0])//abs(end[0] - start[0]), 0
else:
raise ValueError("Must move in a straight line")
def dropPieces(board, loc, num, hand):
for i in range(num):
if board.isEmpty(loc):
place(board, loc, hand.pop())
elif abs(board.getTop(loc)) == 1:
board.getLocation(loc).append(hand.pop())
elif abs(board.getTop(loc)) == 2 and abs(hand[-1]) == 3:
board.getLocation(loc)[-1] = board.getTop(loc)/2
board.getLocation(loc).append(hand.pop())
else:
raise ValueError("This piece can't be placed on that piece")
def checkCarry(board, num):
if num <= board.size:
return None
else:
raise ValueError("You can't pick up that may pieces at once")
def move(board, start, end, dropArray):
checkCarry(board, sum(dropArray))
hand = pickup(board, start, dropArray)
xdir, ydir = getDirection(start, end)
current = start.copy()
for element in dropArray:
current = [current[0] + xdir, current[1] + ydir]
dropPieces(board, current, element, hand)

31
AuxiliaryTestingMethods.py Executable file
View file

@ -0,0 +1,31 @@
def fillSpace(game, loc, val):
game.board.board[loc[0]][loc[1]] = [val]
def fillRow(game, row, val):
for i in range(game.board.size):
fillSpace(game, [row, i], val)
def fillCol(game, col, val):
for i in range(game.board.size):
fillSpace(game, [i, col], val)
def fillBoardEndFull(game):
for i in range(game.board.size):
fillRow(game, i, (-1)**i)
def fillBoardEndPiece(game):
pieces = game.pieces
capstones = game.capstones
for i in range(game.board.size):
for j in range(game.board.size):
if pieces > 0:
fillSpace(game, [i, j], 1)
pieces -= 1
elif capstones > 0:
fillSpace(game, [i, j], 3)
capstones -= 1
def resetBoard(game):
for i in range(game.board.size):
fillRow(game, i, 0)
game.turnCount = 1

61
Board.py Executable file
View file

@ -0,0 +1,61 @@
import collections
class Board(object):
def __init__(self, size):
self.size = size
self.board = [[[0] for i in range(self.size)]for j in range(self.size)]
self.pieces, self.capstones = self.getPieceCount(size)
def getPieceCount(self, size):
if size == 8:
cap, pie = 2, 50
elif size == 7:
cap, pie = 2, 40
elif size == 6:
cap, pie = 1, 30
elif size == 5:
cap, pie = 1, 21
elif size == 4:
cap, pie = 0, 15
else:
cap, pie = 0, 10
return (pie, cap)
def printBoard(self):
for i in range(self.size):
print(self.board[i])
def isAdjacent(self, loc1, loc2):
return (loc1[0] == loc2[0] and abs(loc1[1] - loc2[1]) == 1) or (loc1[1] == loc2[1] and abs(loc1[0] - loc2[0]) == 1)
def onboard(self, loc):
return (loc[0] >= 0 and loc[0] < self.size and (loc[1] >=0 and loc[1] < self.size))
def adjacent(self, loc):
adj = [[loc[0], loc[1]+1], [loc[0], loc[1]-1], [loc[0]+1, loc[1]], [loc[0]-1, loc[1]]]
return list(filter(self.onboard, adj))
def getTop(self, loc):
return self.getLocation(loc)[-1]
def getLocation(self, loc):
return self.board[loc[0]][loc[1]]
def countStack(self, loc):
return len(self.getLocation(loc))
def isEmpty(self, loc):
return len(self.getLocation(loc)) == 1 and self.getTop(loc) == 0
def countRow(self, row):
count = collections.Counter()
for col in self.board[row]:
count = count + collections.Counter(col)
return count
def countTotalPieces(self):
count = collections.Counter()
for i in range(self.size):
count = count + self.countRow(i)
return count

98
End.py Executable file
View file

@ -0,0 +1,98 @@
import collections
def isFull(board):
for row in board.board:
for col in row:
if col[-1] == 0:
return False
return True
def outOfPieces(board):
pC = board.countTotalPieces()
return (pC[1] + pC[2] == board.pieces and pC[3] == board.capstones) or (pC[-1] + pC[-2] == board.pieces and pC[-3] == board.capstones)
def end(board):
en = False
if outOfPieces(board):
en = True
elif isFull(board):
en = True
elif road(board)[0] or road(board)[1]:
en = True
return en
def isRoadPiece(board, loc, player):
mod = -1*((-1)**player)
return board.getTop(loc) == 1*mod or board.getTop(loc) == 3*mod
def isGoal(board, start, loc):
return (start[0] == 0 and loc[0] == board.size-1) or (start[1] == 0 and loc[1] == board.size-1)
def checkRow(board, start, player):
return isRoadPiece(board, [start, 0], player) and roadSearch(board, [start, 0], player)
def checkCol(board, start, player):
return isRoadPiece(board, [0, start], player) and roadSearch(board, [0, start], player)
def roadSearch(board, start, player):
visited = [[False for i in range(board.size)] for j in range(board.size)]
locations = [start]
visited[start[0]][start[1]] = True
while len(locations) > 0:
check = locations.pop(-1)
adj = board.adjacent(check)
for loc in adj:
if not visited[loc[0]][loc[1]] and isGoal(board, start, loc) and isRoadPiece(board, loc, player):
return True
elif not visited[loc[0]][loc[1]] and isRoadPiece(board, loc, player):
locations.append(loc)
visited[loc[0]][loc[1]] = True
return False
def road(board):
p1road, p2road = False, False
for i in range(board.size):
if checkRow(board, i, 1) or checkCol(board, i, 1):
p1road = True
elif checkRow(board, i, 2) or checkCol(board, i, 2):
p2road = True
return p1road, p2road
def points(board, player):
win = player
piecesLeft = board.capstones + board.pieces
if win == 1:
piecesLeft = piecesLeft - (board.countTotalPieces()[1] + board.countTotalPieces()[3])
else:
piecesLeft = piecesLeft - (board.countTotalPieces()[-1] + board.countTotalPieces()[-3])
return (board.size**2) + piecesLeft
def winRoad(board, player=1):
rd = road(board)
if rd[0] and rd[1]:
return player
elif rd[0] == True:
return 1
elif rd[1] == True:
return 2
return False
def flatStones(board, player):
flatCount = 0
for i in range(board.size):
for j in range(board.size):
if isRoadPiece(board, [i,j], player):
flatCount += 1
return flatCount
def winFlat(board):
if flatStones(board, 1) > flatStones(board, 2):
return 1
else:
return 2
def winner(board, player=1):
if winRoad(board, player):
return winRoad(board, player)
else:
return winFlat(board)

View file

@ -1,3 +1,12 @@
# Tak
**Implementation of Tak in Python**
Tak is an abstract strategy game designed by James Earnest and Patrick Rothfuss, taken from Rothfuss' book the Wise Man's Fear.
Rules can be found [here](https://cheapass.com/wp-content/uploads/2016/07/Tak-Beta-Rules.pdf)
This game needs python and pygame installed to run. It should be run from the TakGame.py file
If you enjoy this please consider buying the physical game.
![Program Interface](images/board.png)
My implementation of the game Tak from Wise Man's fear in python

62
Tak.py Executable file
View file

@ -0,0 +1,62 @@
import collections
import Board as boa, End, Actions as act
from copy import deepcopy
#initialize board and pies
class TakGame(object):
def __init__(self, boardsize):
self.board = boa.Board(boardsize)
self.pieces, self.capstones = self.board.getPieceCount(boardsize)
self.turnCount = 1
self.history = []
def logAction(self):
self.history.append(deepcopy(self.board.board))
def undo(self):
if len(self.history) > 0:
self.board.board = self.history.pop()
self.turnCount -= 1
def end(self):
return End.end(self.board)
def getEndResults(self):
player = 2-((self.turnCount+1)%2)
winP = End.winner(self.board, player)
pts = End.points(self.board, player)
return (winP, pts)
def actPlace(self, player, loc, value):
self.logAction()
piece = (-1) * ((-1)**player) * value
if self.turnCount <= 2:
piece = piece * (-1)//abs(piece)
act.place(self.board, loc, piece)
self.turnCount += 1
def checkLegalPlacement(self, loc):
return self.board.isEmpty(loc)
def actMove(self, start, end, dropArray):
self.logAction()
act.move(self.board, start, end, dropArray)
self.turnCount += 1
def checkLegalMoveStart(self, player, loc):
return (player == 1 and self.board.getTop(loc) > 0) or (player == 2 and self.board.getTop(loc) < 0)
def checkLegalDrop(self, loc, held):
return (abs(self.board.getTop(loc)) < 2) or (held == 3 and self.board.getTop(loc) < 3)
def checkLegalPickup(self, loc, num):
return num <= len(self.board.getLocation(loc))
def piecesLeft(self, player):
piecesUsed = self.board.countTotalPieces()
if player == 1:
piecesLeft = self.pieces - (piecesUsed[1] + piecesUsed[2])
capstonesLeft = self.capstones - piecesUsed[3]
else:
piecesLeft = self.pieces - (piecesUsed[-1] + piecesUsed[-2])
capstonesLeft = self.capstones - piecesUsed[-3]
return (piecesLeft, capstonesLeft)

300
TakGame.py Executable file
View file

@ -0,0 +1,300 @@
import pygame, os, sys, itertools
import Tak
#display setup
pygame.init()
#basic settings to use
resolution = (800, 1000)
width, height = 800, 800
colors = {'white':(255, 255, 255), 'black':(0, 0, 0), 'lightBrown':(251, 196, 117), 'darkBrown':(139, 69, 0),
'lightGrey':(150, 150, 150), 'darkGrey':(100, 100, 100)}
win = pygame.display.set_mode(resolution)
pygame.display.set_caption("Tak")
font = pygame.font.SysFont('Arial', 18)
background = pygame.Surface(resolution)
background.fill(colors['black'])
pieceImages = {'lightflat':pygame.image.load('2D pieces/flat-light.png'), 'lightwall':pygame.image.load('2D pieces/wall-light.png'),
'lightcapstone':pygame.image.load('2D pieces/capstone-light.png'), 'darkflat':pygame.image.load('2D pieces/flat-dark.png'),
'darkwall':pygame.image.load('2D pieces/wall-dark.png'), 'darkcapstone':pygame.image.load('2D pieces/capstone-dark.png'),}
#board and button classes
class board(object):
def __init__(self, size):
self.width, self.height = 800, 800
self.size = size
self.squareSize = self.width/size
self.bd = pygame.Surface((self.width, self.height))
self.squareCentres = []
self.color = [colors['lightBrown'], colors['darkBrown']]
self.index = 1
for row in range(size):
for column in range(size):
Square = (row*self.squareSize, column*self.squareSize, self.squareSize, self.squareSize)
if Square not in self.squareCentres:
self.squareCentres.append(Square)
pygame.draw.rect(self.bd, self.color[self.index], Square)
if not (size%2 == 0 and column == size-1):
self.index = (self.index+1)%2
def checkSquare(self, coordinate):
for i in range(len(self.squareCentres)):
square = self.squareCentres[i]
if square[0] < coordinate[0] < square[0] + square[2] and square[1] < coordinate[1] < square[1] + square[3]:
return [i//self.size, i%self.size]
class button(object):
def __init__(self, x, y, text, width = 110, height = 40):
self.width = width
self.height = height
self.x = x
self.y = y
self.text = text
self.disp = renderStandard(text)
#move has to be built in multiple steps and needs the object to hold and output the data in the correct
#format for the move command in game
class buildMove(object):
def __init__(self, start):
self.start = start
self.dropLocations = []
self.hand = 0
self.current = start
self.direction = None
def pickup(self, loc):
if self.same(self.start, loc) and game.checkLegalPickup(loc, self.hand+1):
self.hand += 1
def next(self, loc):
return loc[0] == self.current[0] + self.direction[0] and loc[1] == self.current[1] + self.direction[1]
def same(self, loc1, loc2):
return loc1[0] == loc2[0] and loc1[1] == loc2[1]
def drop(self, loc):
if game.board.isAdjacent(loc, self.start) and self.direction is None and game.checkLegalDrop(loc, game.board.getLocation(self.start)[-self.hand]):
self.direction = [loc[0]-self.start[0], loc[1] - self.start[1]]
self.dropLocations.append(loc)
self.hand -= 1
self.current = loc
elif self.direction is not None and (self.same(self.current, loc) or self.next(loc)) and self.hand > 0 and game.checkLegalDrop(loc, game.board.getLocation(self.start)[-self.hand]):
self.dropLocations.append(loc)
self.hand -= 1
self.current = loc
def dropArray(self):
array = []
count = 0
current = self.dropLocations[0]
for location in self.dropLocations:
if self.same(current, location):
count += 1
else:
array.append(count)
count = 1
current = location
array.append(count)
return array
def getEnd(self):
return self.dropLocations[-1]
#get correct image to draw onto the board for each piece
def selectPieceImage(value):
key = ''
if value > 0:
key += 'light'
else:
key += 'dark'
if abs(value) == 3:
key += 'capstone'
elif abs(value) == 2:
key += 'wall'
else:
key += 'flat'
return pieceImages[key]
#render the board as a printable set to show pieces
def renderPieces(game, board):
for i in range(game.board.size):
for j in range(game.board.size):
pieceStack = game.board.getLocation([i, j])
boardSquare = board.squareCentres[i*board.size+j]
coordinate = boardSquare[:2]
for x in range(len(pieceStack)):
if pieceStack[x] != 0:
if abs(pieceStack[x]) == 2:
image = pygame.transform.scale(selectPieceImage(pieceStack[x]), (int(board.squareSize*0.2), int(board.squareSize*0.6)))
else:
image = pygame.transform.scale(selectPieceImage(pieceStack[x]), (int(board.squareSize*0.6), int(board.squareSize*0.6)))
win.blit(image, (coordinate[0]+int(board.squareSize*(0.05*(x+1))), coordinate[1]+int(board.squareSize*(0.05*(x+1)))))
#check to see what button has been pressed
def checkButtons(coordinate):
for butt in buttons:
if butt.x < coordinate[0] < butt.x + butt.width and butt.y < coordinate[1] < butt.y + butt.height:
return butt.text
#render standard font
def renderStandard(text):
return font.render(text, True, colors['white'])
#display game results
def displayResults():
results = game.getEndResults()
block = pygame.Surface((250, 160))
block.fill(colors['white'])
winText = pygame.font.SysFont('Arial', 40).render('Winner!', True, colors['black'])
winnerText = pygame.font.SysFont('Arial', 30).render('Player ' + str(results[0]), True, colors['black'])
pointText = font.render('Points scored: ' + str(results[1]), True, colors['black'])
win.blit(block, (275, 300))
win.blit(winText, (320, 310))
win.blit(winnerText, (335, 370))
win.blit(pointText, (320, 430))
#display current action
def displayAction():
actionText = [renderStandard("Current Action:")]
if move is not None:
actionText.append(renderStandard('Moving'))
actionText.append(renderStandard('Holding ' + str(move.hand) + ' from ' + str(move.start)))
if move.direction is not None:
actionText.append(renderStandard('Dropping'))
dropArray = move.dropArray()
direction = move.direction
for i in range(len(dropArray)):
location = move.start[0] + (i+1)*direction[0], move.start[1] + (i+1)*direction[1]
actionText.append(renderStandard(str(dropArray[i]) + ' at ' + str(location)))
elif type != 0:
actionText.append(renderStandard('Placing'))
if type == 1:
actionText.append(renderStandard('Flat stone'))
elif type == 2:
actionText.append(renderStandard('Wall'))
elif type == 3:
actionText.append(renderStandard('Capstone'))
else:
actionText.append(renderStandard('No current action'))
start = (270, 820)
for i in range(len(actionText)):
win.blit(actionText[i], (start[0], start[1] + i*20))
#initialize components
table = board(5)
game = Tak.TakGame(5)
pastGames = []
turnLabel = renderStandard('Current Turn: ')
playerLabel = renderStandard('Current Player: ')
sizeLabel = renderStandard('Select game size (will reset game):')
piecesLabel = renderStandard('Pieces left:')
capstonesLabel = renderStandard('Capstones left:')
flatButton = button(20, 820, 'Flat')
wallButton = button(20, 880, 'Wall')
capButton = button(20, 940, 'Capstone')
moveButton = button(150, 820, 'Move')
cancelButton = button(150, 880, 'Cancel')
undoButton = button(150, 940, 'Undo')
threeButton = button(500, 940, '3', 40, 40)
fourButton = button(560, 940, '4', 40, 40)
fiveButton = button(620, 940, '5', 40, 40)
sixButton = button(680, 940, '6', 40, 40)
eightButton = button(740, 940, '8', 40, 40)
buttons = [flatButton, wallButton, capButton, moveButton, undoButton, cancelButton, threeButton, fourButton,
fiveButton, sixButton, eightButton]
#game loop and initilize game specific settings
fps = 60
clock = pygame.time.Clock()
run = True
type = 0
location = None
buildingMove = False
move = None
player = 1
while run:
clock.tick(fps)
player = 2-(game.turnCount%2)
#draw out all the features
win.blit(background, (0,0))
win.blit(table.bd, table.bd.get_rect())
win.blit(turnLabel, (480, 820))
win.blit(renderStandard(str(game.turnCount)), (600, 820))
win.blit(playerLabel, (640, 820))
win.blit(renderStandard(str(player)), (780, 820))
win.blit(piecesLabel, (480, 860))
win.blit(renderStandard(str(game.piecesLeft(player)[0])), (580, 860))
win.blit(capstonesLabel, (640, 860))
win.blit(renderStandard(str(game.piecesLeft(player)[1])), (780, 860))
win.blit(sizeLabel, (480, 900))
renderPieces(game, table)
#actions on events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
mouse = pygame.mouse.get_pos()
selection = checkButtons(mouse)
location = table.checkSquare(mouse)
if selection == 'Flat':
type = 1
elif selection == 'Wall' and game.turnCount > 2:
type = 2
elif selection == 'Capstone' and game.turnCount > 2:
type = 3
elif selection == 'Cancel':
if move is None:
type = 0
else:
move = None
buildingMove = False
elif selection == 'Undo':
if game.turnCount > 1:
game.undo()
elif len(pastGames) > 0:
last = pastGames.pop()
game = last[0]
table = last[1]
elif selection == 'Move':
buildingMove = True
elif selection is not None and selection.isdigit():
pastGames.append((game, table))
game = Tak.TakGame(int(selection))
table = board(int(selection))
elif type != 0 and location is not None and game.checkLegalPlacement(location):
game.actPlace(player, location, type)
location = None
type = 0
elif move is not None and buildingMove:
if move.same(move.start, location):
move.pickup(location)
elif move.hand > 0:
move.drop(location)
else:
game.actMove(move.start, move.getEnd(), move.dropArray())
move = None
buildingMove = False
elif buildingMove and location is not None and game.checkLegalMoveStart(player, location):
move = buildMove(location)
move.pickup(location)
#track if we are hovering over buttons and draw them in the correct color
mouse = pygame.mouse.get_pos()
for butt in buttons:
if butt.x < mouse[0] < butt.x + butt.width and butt.y < mouse[1] < butt.y + butt.height:
pygame.draw.rect(win, colors['lightGrey'], [butt.x, butt.y, butt.width, butt.height])
else:
pygame.draw.rect(win, colors['darkGrey'], [butt.x, butt.y, butt.width, butt.height])
win.blit(butt.disp, (butt.x + 10, butt.y + int(butt.height/4)))
if game.end():
displayResults()
displayAction()
pygame.display.update()
pygame.quit()
sys.exit()

BIN
images/board.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

51
testActions.py Executable file
View file

@ -0,0 +1,51 @@
import pytest, AuxiliaryTestingMethods as aux, Actions
def testPlace(takGame):
aux.resetBoard(takGame)
Actions.place(takGame.board, [1, 1], 1)
assert takGame.board.board[1][1][0] == 1
def testMove(takGame):
aux.resetBoard(takGame)
Actions.place(takGame.board, [1, 1], 1)
Actions.place(takGame.board, [1, 2], 1)
Actions.move(takGame.board, [1, 1], [1, 2], [1])
assert takGame.board.board[1][2][0] == 1
assert takGame.board.board[1][2][1] == 1
assert takGame.board.board[1][1][0] == 0
Actions.move(takGame.board, [1, 2], [3, 2], [1,1])
assert takGame.board.board[1][2][0] == 0
assert takGame.board.board[2][2][0] == 1
assert takGame.board.board[3][2][0] == 1
def testWall(takGame):
aux.resetBoard(takGame)
Actions.place(takGame.board, [1, 1], 1)
Actions.place(takGame.board, [1, 2], 2)
with pytest.raises(ValueError):
Actions.move(takGame.board, [1,1], [1,2], [1])
def testCapstone(takGame):
aux.resetBoard(takGame)
Actions.place(takGame.board, [1, 1], 3)
Actions.place(takGame.board, [1, 2], -2)
Actions.move(takGame.board, [1, 1], [1, 2], [1])
assert takGame.board.board[1][2][0] == -1
assert takGame.board.board[1][2][1] == 3
def testCarryLimit(takGame):
aux.resetBoard(takGame)
takGame.board.board[1][1] = [1,1,1,1,1,1,1,1,1,1]
with pytest.raises(ValueError):
Actions.move(takGame.board, [1,1], [1,2], [9])
def testPiecesLeft(takGame):
aux.resetBoard(takGame)
Actions.place(takGame.board, [1,1], 3)
with pytest.raises(ValueError):
Actions.place(takGame.board, [0, 1], 3)
@pytest.fixture(scope='module')
def takGame():
import Tak
return Tak.TakGame(5)

52
testBasics.py Executable file
View file

@ -0,0 +1,52 @@
import pytest
def testPieceCounts(takGame):
size = takGame.board.size
pieces = takGame.pieces
capstones = takGame.capstones
correct = False
if size == 8 and pieces == 50 and capstones == 2:
correct = True
elif size == 7 and pieces == 40 and capstones == 2:
correct = True
elif size == 6 and pieces == 30 and capstones == 1:
correct = True
elif size == 5 and pieces == 21 and capstones == 1:
correct = True
elif size == 4 and pieces == 15 and capstones == 0:
correct = True
elif size == 3 and pieces == 10 and capstones == 0:
correct = True
assert correct
def testIsAdjacent(takGame):
res = True
size = takGame.board.size
testLoc = [size//2, size//2]
for i in range(size):
for j in range(size):
if (((i==size//2 and abs(j-size//2) ==1) or (j==size//2 and abs(i-size//2) == 1))
is not takGame.board.isAdjacent(testLoc, [i, j])):
res = False
assert res
def testAdjacent(takGame):
correct = True
location = [1, 1]
result = [[0, 1], [1, 0], [1, 2], [2, 1]]
testRes = takGame.board.adjacent(location)
for loc in result:
if loc not in testRes:
correct = False
location = [0,0]
result = [[0, 1], [1, 0]]
testRes = takGame.board.adjacent(location)
for loc in result:
if loc not in testRes:
correct = False
assert correct
@pytest.fixture(scope='module')
def takGame():
import Tak
return Tak.TakGame(5)

70
testCore.py Executable file
View file

@ -0,0 +1,70 @@
import pytest, AuxiliaryTestingMethods as aux
from copy import deepcopy
def testLogAction(takGame):
board = deepcopy(takGame.board.board)
takGame.logAction()
assert(takGame.history[-1] == board)
def testUndo(takGame):
board = deepcopy(takGame.board.board)
takGame.actPlace(1, [0,0], 1)
assert (board != takGame.board.board)
takGame.undo()
assert(board == takGame.board.board)
def testGetEndResults(takGame):
aux.fillRow(takGame, 0, 1)
takGame.turnCount += 1
assert(takGame.getEndResults() == (1, 42))
def testActPlace(takGame):
aux.resetBoard(takGame)
takGame.actPlace(1, [1,1], 1)
assert(takGame.turnCount == 2)
assert(takGame.board.board[1][1][0] == -1)
def testCheckLegalPlacement(takGame):
aux.resetBoard(takGame)
takGame.actPlace(1, [1,1], 1)
assert(takGame.checkLegalPlacement([0,0]))
assert(not takGame.checkLegalPlacement([1,1]))
def testActMove(takGame):
aux.resetBoard(takGame)
aux.fillRow(takGame, 0, 1)
takGame.actMove([0,0], [1,0], [1])
assert(takGame.board.board[0][0][0] == 0)
assert(takGame.board.board[1][0][0] == 1)
assert(takGame.turnCount == 2)
def testCheckLegalMoveStart(takGame):
aux.resetBoard(takGame)
aux.fillSpace(takGame, [2,0], -1)
assert(takGame.checkLegalMoveStart(2, [2,0]))
assert(not takGame.checkLegalMoveStart(1, [2,0]))
def testCheckLegalDrop(takGame):
aux.resetBoard(takGame)
aux.fillSpace(takGame, [0,0], 3)
aux.fillSpace(takGame, [0,1], 2)
aux.fillSpace(takGame, [0,2], 1)
assert(not takGame.checkLegalDrop([0,0], 1))
assert(not takGame.checkLegalDrop([0,0], 2))
assert(not takGame.checkLegalDrop([0,0], 3))
assert(not takGame.checkLegalDrop([0,1], 1))
assert(not takGame.checkLegalDrop([0,1], 2))
assert(takGame.checkLegalDrop([0,1], 3))
assert(takGame.checkLegalDrop([0,2], 1))
def testPiecesLeft(takGame):
aux.resetBoard(takGame)
aux.fillRow(takGame, 0, 1)
assert(takGame.piecesLeft(1) == (16, 1))
aux.fillSpace(takGame, [1,1], 3)
assert(takGame.piecesLeft(1) == (16, 0))
@pytest.fixture(scope='module')
def takGame():
import Tak
return Tak.TakGame(5)

31
testEndCondition.py Executable file
View file

@ -0,0 +1,31 @@
import pytest, AuxiliaryTestingMethods as aux, End
def testEndPieces(takGame):
aux.resetBoard(takGame)
correct = True
aux.fillBoardEndPiece(takGame)
if not End.end(takGame.board):
correct = False
assert correct
def testEndFull(takGame):
aux.resetBoard(takGame)
correct = True
aux.fillBoardEndFull(takGame)
if not End.end(takGame.board):
correct = False
assert correct
def testEndRoad(takGame):
aux.resetBoard(takGame)
aux.fillCol(takGame, 1, 1)
assert End.end(takGame.board)
def testNotEnd(takGame):
aux.resetBoard(takGame)
assert not End.end(takGame.board)
@pytest.fixture(scope='module')
def takGame():
import Tak
return Tak.TakGame(5)

33
testRoadCondition.py Executable file
View file

@ -0,0 +1,33 @@
import pytest, AuxiliaryTestingMethods as aux, End
def testNoRoad(takGame):
aux.resetBoard(takGame)
ans = End.road(takGame.board)
assert not ans[0] and not ans[1]
def testRoadVertical(takGame):
correct = True
aux.resetBoard(takGame)
aux.fillCol(takGame, 1, 1)
ans = End.road(takGame.board)
assert ans[0] and not ans[1]
aux.resetBoard(takGame)
aux.fillCol(takGame, 1, -1)
ans = End.road(takGame.board)
assert ans[1] and not ans[0]
def testRoadHorizontal(takGame):
correct = True
aux.resetBoard(takGame)
aux.fillRow(takGame, 1, 1)
ans = End.road(takGame.board)
assert ans[0] and not ans[1]
aux.resetBoard(takGame)
aux.fillRow(takGame, 1, -1)
ans = End.road(takGame.board)
assert ans[1] and not ans[0]
@pytest.fixture(scope='module')
def takGame():
import Tak
return Tak.TakGame(5)

45
testWinCondition.py Executable file
View file

@ -0,0 +1,45 @@
import pytest, AuxiliaryTestingMethods as aux, End
def testPoints(takGame):
aux.resetBoard(takGame)
assert End.points(takGame.board, 1) == takGame.board.pieces + takGame.board.capstones + (takGame.board.size**2)
aux.fillRow(takGame, 0, 1)
aux.fillSpace(takGame, [0, 0], 0)
assert End.points(takGame.board, 1) == takGame.board.pieces + takGame.board.capstones + (takGame.board.size**2) - (takGame.board.size-1)
aux.fillRow(takGame, 1, -1)
aux.fillRow(takGame, 2, -1)
assert End.points(takGame.board, 2) == takGame.board.pieces + takGame.board.capstones + (takGame.board.size**2) - (takGame.board.size*2)
def testWinnerRoad(takGame):
aux.resetBoard(takGame)
aux.fillRow(takGame, 0, 1)
assert End.winRoad(takGame.board, 1) == 1
aux.resetBoard(takGame)
aux.fillRow(takGame, 0, -1)
assert End.winRoad(takGame.board, 1) == 2
aux.resetBoard(takGame)
assert End.winRoad(takGame.board, 1) == False
aux.fillRow(takGame, 0, 1)
aux.fillRow(takGame, 1, -1)
assert End.winRoad(takGame.board, 1) == 1
assert End.winRoad(takGame.board, 2) == 2
def testWinnerOther(takGame):
aux.resetBoard(takGame)
aux.fillRow(takGame, 0, 1)
aux.fillRow(takGame, 1, 1)
aux.fillCol(takGame, takGame.board.size-1, 0)
assert End.winner(takGame.board) == 1
aux.resetBoard(takGame)
aux.fillRow(takGame, 0, -1)
aux.fillRow(takGame, 1, -1)
aux.fillCol(takGame, takGame.board.size-1, 0)
assert End.winner(takGame.board) == 2
aux.fillRow(takGame, 0, 1)
aux.fillSpace(takGame, [0, takGame.board.size-1], 0)
assert End.winner(takGame.board) == 2
@pytest.fixture(scope='module')
def takGame():
import Tak
return Tak.TakGame(5)