Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import curses
- import copy
- import os
- import sys
- import time
- main_board = None
- window = None
- selected_square_x = 0
- selected_square_y = 0
- dot_file = open("file.dot", "w+")
- dot_file.write("digraph a_graph {")
- class Piece:
- def __init__(self, is_white):
- self.is_white = is_white
- is_white = True
- is_king = False
- def __str__(self):
- if self.is_white:
- if self.is_king:
- return "white king"
- else:
- return "white"
- else:
- if self.is_king:
- return "black king"
- else:
- return "black"
- def better_str(self):
- if self.is_white:
- if self.is_king:
- return "wk"
- else:
- return "w "
- else:
- if self.is_king:
- return "bk"
- else:
- return "b "
- class Move:
- start_x = -1
- start_y = -1
- end_x = -1
- end_y = -1
- def __init__(self, start_x, start_y, end_x, end_y):
- self.start_x = start_x
- self.start_y = start_y
- self.end_x = end_x
- self.end_y = end_y
- def __str__(self):
- return "start_x" + self.start_x + "start_y" + self.start_y + "end_x" + self.end_x + "end_y" + self.end_y
- board_count = 0
- class Board:
- pieces = [[]]
- message = ""
- board_number = 0
- def __init__(self, pieces):
- global board_count
- self.pieces = pieces
- self.board_number = board_count
- board_count += 1
- def score(self):
- def white():
- out = 0
- for row in self.pieces:
- for piece in row:
- if piece is not None:
- if piece.is_white:
- out += 1
- return out
- def black():
- out = 0
- for row in self.pieces:
- for piece in row:
- if piece is not None:
- if not piece.is_white:
- out += 1
- return out
- return white() - black()
- def apply_move(self, move):
- assert (is_valid(self, move))
- piece = self.pieces[move.start_y][move.start_x]
- self.pieces[move.start_y][move.start_x] = None
- self.pieces[move.end_y][move.end_x] = piece
- if is_taking_piece(move):
- middle_x = (move.start_x + move.end_x) / 2
- middle_y = (move.start_y + move.end_y) / 2
- self.pieces[middle_y][middle_x] = None
- promote_pieces(self)
- def render(self):
- global window, selected_square_y, selected_square_x
- window.erase()
- for y, row in enumerate(self.pieces):
- for x, piece in enumerate(row):
- if piece is None:
- if x == selected_square_x and y == selected_square_y:
- window.addstr(y, 2 * x, " ", curses.color_pair(blue_on_green))
- elif (y + x) % 2 == 1:
- window.addstr(y, 2 * x, " ", curses.color_pair(blue_on_black))
- else:
- window.addstr(y, 2 * x, " ", curses.color_pair(blue_on_white))
- elif piece.is_white:
- piece_name = " o"
- if piece.is_king:
- piece_name = "ko"
- window.addstr(y, 2 * x, piece_name, curses.color_pair(white_on_black))
- if x == selected_square_x and y == selected_square_y:
- window.addstr(y, 2 * x, piece_name, curses.color_pair(white_on_green))
- elif not piece.is_white:
- piece_name = " x"
- if piece.is_king:
- piece_name = "kx"
- window.addstr(y, 2 * x, piece_name, curses.color_pair(blue_on_black))
- if x == selected_square_x and y == selected_square_y:
- window.addstr(y, 2 * x, piece_name, curses.color_pair(blue_on_green))
- window.addstr(9, 0, self.message)
- window.refresh()
- # time.sleep(0.1)
- def __str__(self):
- out = "["
- for row in self.pieces:
- out += "["
- for piece in row:
- out += ','
- out += piece.__str__()
- out += "]\n"
- out += "]"
- return out
- def better_str(self):
- out = "["
- for row in self.pieces:
- out += "["
- for piece in row:
- out += ','
- if piece is None:
- out += " "
- else:
- out += piece.better_str()
- out += "]\n"
- out += "]"
- return out
- def is_taking_piece(move):
- if abs(move.end_x - move.start_x) == 2 and abs(move.end_y - move.start_y) == 2:
- return True
- return False
- def is_valid(board, move):
- # in my version of checkers pieces move diagonally by one piece
- # or take by moving 2 squares diagonally
- # kings can take backwards
- piece = board.pieces[move.start_y][move.start_x] # gets the piece being moved
- if piece is None:
- return False # move is not valid since there is no piece
- def is_direction_correct():
- if piece.is_king:
- return True # kings can move in any direction they want as long as its diagonal
- if piece.is_white:
- # white pieces start at the bottom, so they have to move up unless they're king
- if move.start_y <= move.end_y:
- return False
- return True
- elif not piece.is_white:
- if move.start_y >= move.end_y:
- return False
- return True
- else:
- # the piece is nether white nor black. This can't be right
- assert False
- def is_diagonal():
- if abs(move.end_x - move.start_x) == 1 and abs(move.end_y - move.start_y) == 1:
- return True
- elif abs(move.end_x - move.start_x) == 2 and abs(move.end_y - move.start_y) == 2:
- return True
- return False
- def is_valid_take():
- middle_piece_x = (move.end_x + move.start_x) / 2
- middle_piece_y = (move.end_y + move.start_y) / 2
- middle_piece = board.pieces[middle_piece_y][middle_piece_x]
- if middle_piece is None:
- return False # you can't take nothing
- if piece.is_white:
- if middle_piece.is_white:
- return False # you can't take your own piece
- else:
- if not middle_piece.is_white:
- return False
- return True
- def is_destination_empty():
- destination = board.pieces[move.end_y][move.end_x]
- if destination == None:
- return True
- return False
- def is_destination_on_board():
- if move.end_x < 8 and move.end_y < 8:
- if move.end_x >= 0 and move.end_y >= 0:
- return True
- return False
- if not is_destination_on_board():
- return False
- if not is_direction_correct():
- return False
- if not is_diagonal():
- return False
- if not is_destination_empty():
- return False
- if is_taking_piece(move):
- if not is_valid_take():
- return False
- return True
- def white_win_check():
- def is_white_winning():
- for row in main_board.pieces:
- for piece in row:
- if piece is not None and not piece.is_white:
- return False
- return True
- if is_white_winning():
- curses.endwin()
- print "white wins"
- def black_win_check():
- def is_black_winning():
- for row in main_board.pieces:
- for piece in row:
- if piece is not None and piece.is_white:
- return False
- return True
- if is_black_winning():
- curses.endwin()
- print "black wins"
- def promote_pieces(board):
- for x,piece in enumerate(board.pieces[0]):
- if piece is not None and piece.is_white:
- piece.is_king = True
- # print "promoting:" + str(x)
- for x,piece in enumerate(board.pieces[7]):
- if piece is not None and not piece.is_white:
- piece.is_king = True
- # print "promoting:" + str(x)
- def position_evaluate(board, depth, is_white_moving):
- def not_slow_copy(array):
- out = []
- for row in array:
- out.append(copy.deepcopy(row))
- return out
- if depth == 0:
- return board.score(), None
- else:
- boards = []
- for y, row in enumerate(board.pieces):
- for x, piece in enumerate(row):
- if piece is None:
- continue
- if piece.is_white != is_white_moving:
- continue
- moves = [
- Move(x, y, x + 1, y + 1),
- Move(x, y, x + 1, y - 1),
- Move(x, y, x - 1, y + 1),
- Move(x, y, x - 1, y - 1),
- Move(x, y, x + 2, y + 2),
- Move(x, y, x + 2, y - 2),
- Move(x, y, x - 2, y + 2),
- Move(x, y, x - 2, y - 2)
- ]
- for move in moves:
- if is_valid(board, move):
- board_copy = Board(not_slow_copy(board.pieces))
- board_copy.apply_move(move)
- boards.append((board_copy, move))
- dot_file.write(
- "a" + str(board_copy.board_number) + " [label =\"" + board_copy.better_str() + "\"];")
- dot_file.write("a" + str(board.board_number) + " -> a" + str(board_copy.board_number) + ";")
- evaluated_moves = []
- for board, move in boards:
- eval, previous_move = position_evaluate(
- board,
- depth - 1,
- not is_white_moving
- )
- evaluated_moves.append([eval, (move, previous_move)])
- if is_white_moving:
- max = [-100000000, None]
- for evaluated_move in evaluated_moves:
- if evaluated_move[0] > max[0]:
- max = evaluated_move
- return max
- else:
- min = [100000000, None]
- for evaluated_move in evaluated_moves:
- if evaluated_move[0] < min[0]:
- min = evaluated_move
- return min
- def main_loop():
- def get_key_presses():
- global selected_square_y, selected_square_x
- while True:
- key = int(window.getch())
- if key == 10:
- return None
- elif key == curses.KEY_UP:
- selected_square_y -= 1
- elif key == curses.KEY_DOWN:
- selected_square_y += 1
- elif key == curses.KEY_LEFT:
- selected_square_x -= 1
- elif key == curses.KEY_RIGHT:
- selected_square_x += 1
- main_board.render()
- def ask_for_white_piece():
- white_win_check()
- black_win_check()
- main_board.message = "Please select a white piece"
- window.refresh()
- get_key_presses()
- ask_for_white_move(selected_square_x, selected_square_y)
- def ask_for_white_move(x, y):
- main_board.message = "Please select the square you want your piece to go to"
- window.refresh()
- get_key_presses()
- move = Move(x, y, selected_square_x, selected_square_y)
- if is_valid(main_board, move):
- main_board.apply_move(move)
- do_black_move()
- else:
- main_board.message = "Invalid Move"
- main_board.render()
- window.refresh()
- time.sleep(2)
- ask_for_white_piece()
- def ask_for_black_piece():
- main_board.message = "Please select a black piece"
- window.refresh()
- get_key_presses()
- ask_for_black_move(selected_square_x, selected_square_y)
- def ask_for_black_move(x, y):
- main_board.message = "Please select the square you want your piece to go to"
- window.refresh()
- get_key_presses()
- move = Move(x, y, selected_square_x, selected_square_y)
- if is_valid(main_board, move):
- main_board.apply_move(move)
- ask_for_white_piece()
- else:
- main_board.message = "Invalid Move"
- window.refresh()
- time.sleep(0.5)
- ask_for_black_piece()
- def do_black_move():
- eval, move = position_evaluate(main_board, 4, False)
- if move is None:
- curses.endwin()
- print "stalemate detected"
- move = move[0]
- assert (is_valid(main_board, move))
- main_board.apply_move(move)
- ask_for_white_piece()
- global main_board, window
- while True:
- main_board.render()
- ask_for_white_piece()
- white_on_black = 1
- white_on_white = 2
- white_on_green = 5
- blue_on_white = 3
- blue_on_black = 4
- blue_on_green = 6
- screen = None
- text_window = None
- def main():
- global main_board, window, screen, text_window
- main_board = Board([[None, Piece(False), None, Piece(False), None, Piece(False), None, Piece(False)],
- [Piece(False), None, Piece(False), None, Piece(False), None, Piece(False), None],
- [None, Piece(False), None, Piece(False), None, Piece(False), None, Piece(False)],
- [None, None, None, None, None, None, None, None],
- [None, None, None, None, None, None, None, None],
- [Piece(True), None, Piece(True), None, Piece(True), None, Piece(True), None],
- [None, Piece(True), None, Piece(True), None, Piece(True), None, Piece(True)],
- [Piece(True), None, Piece(True), None, Piece(True), None, Piece(True), None]
- ])
- screen = curses.initscr()
- curses.start_color()
- curses.use_default_colors()
- curses.init_pair(white_on_black, curses.COLOR_WHITE, curses.COLOR_BLACK)
- curses.init_pair(white_on_white, curses.COLOR_YELLOW, curses.COLOR_WHITE)
- curses.init_pair(blue_on_white, curses.COLOR_BLUE, curses.COLOR_WHITE)
- curses.init_pair(blue_on_black, curses.COLOR_BLUE, curses.COLOR_BLACK)
- curses.init_pair(blue_on_green, curses.COLOR_BLUE, curses.COLOR_GREEN)
- curses.init_pair(white_on_green, curses.COLOR_WHITE, curses.COLOR_GREEN)
- curses.curs_set(0)
- window = curses.newwin(0, 0)
- text_window = curses.newwin(9, 0)
- window.keypad(1)
- window.nodelay(1)
- main_loop()
- curses.wrapper(main())
- #main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement