Added game: brandubh

This commit is contained in:
sloumdrone 2019-04-25 20:11:47 -07:00
parent 3a1a260196
commit 321b04887b
5 changed files with 226 additions and 4 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

205
brandubh.py Normal file
View File

@ -0,0 +1,205 @@
# https://boardgamegeek.com/thread/344992/brandubh-or-starting-examine-tafl-games-play
# https://en.wikipedia.org/wiki/Tafl_games
class Brandubh:
def __init__(self, data):
self.game_name = '\nBrandubh\n'
self.pieces = [' a ', ' d ']
self.winner = data['winner']
self.current_player = data['current_ps_turn']
self.piece = self.pieces[data['piece_index']]
self.instructions = 'Coming soon...'
self.p1 = data['p1']
self.p2 = data['p2']
self.board = data['board']
self.piece_index = data['piece_index']
def print_challenge_text(self):
print(self.game_name)
if self.winner:
print('{} vs. {}: {} won!'.format(self.p1, self.p2, self.winner))
else:
print('{} vs. {}: {}\'s turn {}'.format(self.p1, self.p2, self.current_player, self.piece))
def alpha_to_number(self, move):
table_str = {"a": 0, "b": 1, "c": 2, "d": 3, "e": 4, "f": 5, "g": 6}
table_num = {"1": 0, "2": 1, "3": 2, "4": 3, "5": 4, "6": 5, "7": 6}
if move[0] in table_str and move[1] in table_num:
return [table_str[move[0]], table_num[move[1]]]
return False
def print_board(self):
letters = ['A','B','C','D','E','F','G']
print('\n\n ' + ''.join([' ' + str(i) + ' ' for i in range(1,8)]))
for x in range(7):
print(' ' + letters[x] + ''.join(self.board[x]))
print('')
def get_input(self):
print("Enter your move as piece then destination (ex 'B1 B5')")
print('Or (q)uit, (f)orfeit, (instructions).\n')
while True:
move = input('> ')
if move in ['q', 'quit', 'exit']:
return False
elif move in ['f', 'forfeit']:
while True:
verify = input('Are you sure (y/n)? ')
if verify in ['y', 'yes']:
self.winnder = self.p1 if self.p2 == self.current_player else self.p2
res = {"winner": self.winner, "board": self.board, "move": False, "message": "{} forfeit, {} wins!".format(self.current_player, self.winner)}
return res
elif verify in ['n', 'no']:
print('Forfeit canceled')
return False
elif move in ['i', 'instructions']:
print(self.instructions)
continue
elif len(move) != 5:
issue = 'many' if len(move) > 5 else 'few'
print("Invalid entry, too {} characters".format(issue))
continue
else:
moves = move.split(" ", 1)
if len(moves) != 2:
print("Invalid entry")
continue
moves[0] = list(moves[0].strip().lower())
moves[1] = list(moves[1].strip().lower())
start = self.alpha_to_number(moves[0])
end = self.alpha_to_number(moves[1])
piece = self.board[start[0]][start[1]]
if not start or not end:
print("Invalid coordinates")
continue
if piece.lower() != self.piece:
print("That is not a valid piece to move. Try again...")
continue
validation = self.validate_move(start, end, piece)
if not validation["success"]:
print(validation["error"])
continue
self.do_move(start, end)
self.do_captures(end)
status = self.game_over()
res = {'winner': self.winner, 'board': self.board, 'move': True}
if status:
res["winner"] = status
res["message"] = "{} won the match!".format(status)
else:
res['message'] = "Your move has been placed."
return res
def validate_move(self, beg, end, icon):
king = (icon == " D ")
if beg[0] < 0 or beg[1] < 0 or end[0] < 0 or end[1] < 0 or beg[0] > 6 or beg[1] > 6 or end[0] > 6 or end[1] > 6:
return {
"success": False,
"error": "That move would take you off the board!"
}
if beg[0] != end[0] and beg[1] != end[1]:
return {
"success": False,
"error": "You must move orthagonally..."
}
if not king and end in [[0,0],[0,6],[6,0],[6,6],[3,3]]:
return {
"success": False,
"error": "Only the king ('D') can move to that space!"
}
direction = self.get_direction(beg, end)
run = beg.copy()
while run != end:
run = [run[0] + direction[0], run[1] + direction[1]]
if self.board[run[0]][run[1]] in [' a ', ' d ', ' D ']:
return {
"success": False,
"error": "There is a piece in the way!"
}
return {"success": True, "error": ""}
def do_move(self, beg, end):
end_piece = self.board[end[0]][end[1]]
self.board[end[0]][end[1]] = self.board[beg[0]][beg[1]]
self.board[beg[0]][beg[1]] = end_piece
if beg == [3,3]:
self.board[3][3] = ' * '
def get_direction(self, b, e):
dir1 = e[0] - b[0]
dir2 = e[1] - b[1]
if dir1 > 0:
dir1 = 1
elif dir1 < 0:
dir1 = -1
if dir2 > 0:
dir2 = 1
elif dir2 < 0:
dir2 = -1
return [dir1, dir2]
def do_captures(self, pos):
enemy = self.pieces[abs(self.piece_index - 1)]
friend = self.piece
dirs = [[0,1],[0,-1],[1,0],[-1,0]]
for x in dirs:
start = pos.copy()
remove = []
steps = 0
while True:
prev = start.copy()
start[0] += x[0]
start[1] += x[1]
if start[0] < 0 or start[1] < 0 or start[0] > 6 or start[1] > 6:
break
steps += 1
if steps % 2 == 0:
if self.board[start[0]][start[1]].lower() in [friend, ' * '] and start != [3,3]:
self.board[prev[0]][prev[1]] = ' - '
continue
else:
break
else:
if self.board[start[0]][start[1]].lower() == enemy:
continue
else:
break
def game_over(self):
count = self.count_pieces()
if count[" D "] == 0:
return self.p1
elif count[" a "] == 0:
return self.p2
elif self.board[0][0] == " D " or self.board[0][6] == " D " or self.board[6][0] == " D " or self.board[6][6] == " D ":
return self.p2
return False
def count_pieces(self):
holder = {" a ": 0, " d ": 0, " D ": 0}
for x in self.board:
for y in x:
if y in [" a ", " d ", " D "]:
holder[y] += 1
return holder
def is_king(self, row, col):
piece = self.board[row][col]
if piece == ' D ':
return True
return False

25
oberon
View File

@ -7,6 +7,7 @@ import subprocess
import json
from gomoku import Gomoku
from isola import Isola
from brandubh import Brandubh
version = '0.8.0'
home_folder = os.path.expanduser('~')
@ -70,6 +71,8 @@ def play_game(gid):
game = Gomoku(state)
elif state['game_type'] == 'isola':
game = Isola(state)
elif state['game_type'] == 'brandubh':
game = Brandubh(state)
print_header()
game.print_challenge_text()
@ -86,7 +89,6 @@ def play_game(gid):
play = game.get_input()
if not play:
# A false value for play would occur from a forfeit
sys.exit(0)
else:
q2 = "UPDATE games SET game_board = ?, turn = ?, winner = ? WHERE rowid = ?"
@ -143,12 +145,12 @@ def create_game(enemy):
return False
print_header()
print('Which game would you like to play?\n\n(1) Gomoku/Five In a Row\n(2) Isola\n\nor (Q)uit')
print('Which game would you like to play?\n\n(1) Gomoku/Five In a Row\n(2) Isola\n(3) Brandubh\n\nor (Q)uit')
while True:
game = input('> ')
if game.lower() == 'q':
sys.exit(0)
elif not game in ['1', '2']:
elif not game in ['1', '2', '3']:
continue
break
@ -156,12 +158,27 @@ def create_game(enemy):
if game == '1':
game_board = [[' · ' for y in range(15)] for x in range(15)]
game_choice = 'gomoku'
else:
elif game == '2':
board = [[ ' - ' for y in range(7)] for x in range(7)]
board[0][3] = ' X '
board[6][3] = ' O '
game_board = {'board': board, 'p1': [0,3], 'p2': [6,3]}
game_choice = 'isola'
elif game == '3':
game_board = [[ ' - ' for y in range(7)] for x in range(7)]
game_board[0][0] = ' * '
game_board[0][6] = ' * '
game_board[6][0] = ' * '
game_board[6][6] = ' * '
for x in [0,1,5,6]:
game_board[3][x] = ' a '
game_board[x][3] = ' a '
for x in [2,4]:
game_board[3][x] = ' d '
game_board[x][3] = ' d '
game_board[3][3] = ' D '
game_choice = 'brandubh'
q = "INSERT INTO games VALUES (?, ?, ?, ?, ?, ?, ?)"
v = (username, enemy, game_choice, 'playing', json.dumps(game_board), 1, None)