mirror of
https://gitlab.com/oloturia/damastodon.git
synced 2024-11-16 00:20:46 +01:00
162 lines
5.4 KiB
Python
Executable file
162 lines
5.4 KiB
Python
Executable file
#!/usr/bin/python3
|
|
|
|
def draw_checkerboard(status,space="▒",white_norm="h",white_knight="H",black_norm="b",black_knight="B",empty=" ",frstrow=" abcdefgh\n"):
|
|
bstr = ""
|
|
bstr += frstrow
|
|
for row in range(0,len(status)):
|
|
bstr += str(row+1)+""
|
|
|
|
if row % 2 == 0:
|
|
bstr += space
|
|
for cell in range(0,int(len(status)/2)):
|
|
if status[row][cell] == 1: #black normal piece
|
|
bstr += black_norm
|
|
elif status[row][cell] == 2: #white normal piece
|
|
bstr += white_norm
|
|
elif status[row][cell] == 3: #black knight piece
|
|
bstr += black_knight
|
|
elif status[row][cell] == 4: #white knight piece
|
|
bstr += white_knight
|
|
else: #empty
|
|
bstr += empty
|
|
if (cell < 3):
|
|
bstr += space
|
|
if row % 2 !=0:
|
|
bstr += space+"\n"
|
|
else:
|
|
bstr += "\n"
|
|
return bstr
|
|
|
|
def position_resolver(pos,board):
|
|
row,col = row_column_translation(pos[1],pos[0])
|
|
if (col == -1):
|
|
return -1
|
|
else:
|
|
return board[row][col]
|
|
|
|
def row_column_translation(row,col):
|
|
row = int(row) - 1
|
|
if row % 2 != 0:
|
|
cols = range(ord("a"),ord("a")+7,2)
|
|
else:
|
|
cols = range(ord("b"),ord("b")+7,2)
|
|
if ord(col) not in cols:
|
|
return -1,-1
|
|
else:
|
|
return row,cols.index(ord(col))
|
|
|
|
def valid_move(pos_toParse,turn,board):
|
|
pos = pos_toParse.split(" ") #tricky part, pos[0] is the starting cell, pos[1] to pos[n] the destination point(s), for every coord, [x][0] is the column (the letter) and [x][1] the row (the number)
|
|
for rowcol in pos:
|
|
if (rowcol[0] not in ("a","b","c","d","e","f","g","h")) or (rowcol[1] not in ("1","2","3","4","5","6","7","8")): #check if the positions are valid
|
|
return -1
|
|
row_start,col_start = row_column_translation(pos[0][1],pos[0][0])
|
|
if(row_start == -1):
|
|
return -1
|
|
if turn == 1: #black turn
|
|
valid_piece = (1,3)
|
|
foe_piece = (2,4)
|
|
else: #white turn
|
|
valid_piece = (2,4)
|
|
foe_piece = (1,3)
|
|
start_cell = position_resolver(pos[0],board)
|
|
if start_cell not in valid_piece: #selected an opponent's piece or an empty cell
|
|
return -1
|
|
if ((start_cell == 1 and abs(ord(pos[1][0]) - ord(pos[0][0])) == 1 and ord(pos[0][1]) - ord(pos[1][1]) == -1) or (start_cell == 2 and abs(ord(pos[1][0]) - ord(pos[0][0])) == 1 and ord(pos[0][1]) - ord(pos[1][1]) == 1) or ((start_cell == 4 or start_cell == 3) and abs(ord(pos[1][0]) - ord(pos[0][0])) == 1 and abs(ord(pos[1][1]) - ord(pos[0][1])) == 1) and len(pos) == 2 ):
|
|
move_to = position_resolver(pos[1],board) #check non-capturing movement, to be valid it must be 1 col shift and 1 row shift, for norm pieces direction is important, and it must be a single move
|
|
if (move_to == 0): #if the cell is empty, the move is valid
|
|
row,col = row_column_translation(pos[0][1],pos[0][0])
|
|
board[row][col] = 0
|
|
row,col = row_column_translation(pos[1][1],pos[1][0])
|
|
if ((row == 0) and start_cell == 2): #piece promotion
|
|
start_cell = 4
|
|
if ((row == 7) and start_cell == 1):
|
|
start_cell = 3
|
|
board[row][col] = start_cell
|
|
return board
|
|
else:
|
|
return -1
|
|
else:
|
|
for x in range(0,len(pos) -1):
|
|
if (start_cell == 1 and abs(ord(pos[1][0]) - ord(pos[0][0])) == 2 and ord(pos[0][1]) - ord(pos[1][1]) == -2) or (start_cell == 2 and abs(ord(pos[1][0]) - ord(pos[0][0])) == 2 and ord(pos[0][1]) - ord(pos[1][1]) == 2) or ((start_cell == 4 or start_cell == 3) and abs(ord(pos[1][0]) - ord(pos[0][0])) == 2 and abs(ord(pos[1][1]) - ord(pos[0][1])) == 2):
|
|
move_to = position_resolver(pos[1],board)
|
|
if (move_to == 0): #check if destination is empty
|
|
shift_x = int((ord(pos[1][0]) - ord(pos[0][0]))/2)
|
|
shift_y = int((ord(pos[1][1]) - ord(pos[0][1]))/2)
|
|
if (start_cell == 1):#normal pieces can capture kings (to do: optional rule)
|
|
foe_piece = (2,4)
|
|
#foe_piece = (2,)
|
|
elif (start_cell == 2):
|
|
foe_piece = (1,3)
|
|
#foe_piece = (1,)
|
|
row,col = row_column_translation(chr(ord(pos[0][1])+shift_y),chr(ord(pos[0][0])+shift_x)) #check if an opponent piece lies in between start and destination
|
|
if (board[row][col] in foe_piece):
|
|
board[row][col] = 0
|
|
row,col = row_column_translation(pos[0][1],pos[0][0])
|
|
board[row][col] = 0
|
|
row,col = row_column_translation(pos[1][1],pos[1][0])
|
|
board[row][col] = start_cell
|
|
if ((row == 0) and start_cell == 2): #piece promotion
|
|
start_cell = 4
|
|
if ((row == 7) and start_cell == 1):
|
|
start_cell = 3
|
|
pos.pop(0) #if there are other moves this check loops
|
|
else:
|
|
return -1
|
|
else:
|
|
return -1
|
|
else:
|
|
return -1
|
|
return board
|
|
|
|
def init_board():
|
|
checkerboard = []
|
|
for row in range(0,8):
|
|
if (row <= 2):
|
|
checkerboard.append([1,1,1,1])
|
|
elif (row >= 5):
|
|
checkerboard.append([2,2,2,2])
|
|
else:
|
|
checkerboard.append([0,0,0,0])
|
|
return checkerboard
|
|
|
|
def checkWin(board):
|
|
black_won = True
|
|
white_won = True
|
|
for row in board:
|
|
if (1 in row) or (3 in row):
|
|
white_won = False
|
|
if (2 in row) or (4 in row):
|
|
black_won = False
|
|
return (white_won,black_won)
|
|
|
|
def main():
|
|
main_board = init_board()
|
|
s = ""
|
|
turn = False
|
|
while (s !="q"):
|
|
vis_board = draw_checkerboard(main_board)
|
|
print(vis_board)
|
|
if turn:
|
|
s = input("Black move:")
|
|
else:
|
|
s = input("White move:")
|
|
if (s !="q"):
|
|
result = valid_move(s,turn,main_board)
|
|
if result != -1:
|
|
main_board = result
|
|
winner = checkWin(main_board)
|
|
if winner[0]:
|
|
print("White won this game.")
|
|
return turn
|
|
if winner[1]:
|
|
print("Black won this game.")
|
|
return turn
|
|
turn = not turn
|
|
else:
|
|
print("Invalid move")
|
|
return -1
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
quit()
|