Advertisement
Guest User

Untitled

a guest
Oct 28th, 2016
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.35 KB | None | 0 0
  1. import curses
  2. import copy
  3. import os
  4. import sys
  5. import time
  6.  
  7. main_board = None
  8. window = None
  9.  
  10. selected_square_x = 0
  11. selected_square_y = 0
  12.  
  13. dot_file = open("file.dot", "w+")
  14. dot_file.write("digraph a_graph {")
  15.  
  16.  
  17. class Piece:
  18. def __init__(self, is_white):
  19. self.is_white = is_white
  20.  
  21. is_white = True
  22. is_king = False
  23.  
  24. def __str__(self):
  25. if self.is_white:
  26. if self.is_king:
  27. return "white king"
  28. else:
  29. return "white"
  30. else:
  31. if self.is_king:
  32. return "black king"
  33. else:
  34. return "black"
  35.  
  36. def better_str(self):
  37. if self.is_white:
  38. if self.is_king:
  39. return "wk"
  40. else:
  41. return "w "
  42. else:
  43. if self.is_king:
  44. return "bk"
  45. else:
  46. return "b "
  47.  
  48.  
  49. class Move:
  50. start_x = -1
  51. start_y = -1
  52. end_x = -1
  53. end_y = -1
  54.  
  55. def __init__(self, start_x, start_y, end_x, end_y):
  56. self.start_x = start_x
  57. self.start_y = start_y
  58. self.end_x = end_x
  59. self.end_y = end_y
  60.  
  61. def __str__(self):
  62. return "start_x" + self.start_x + "start_y" + self.start_y + "end_x" + self.end_x + "end_y" + self.end_y
  63.  
  64.  
  65. board_count = 0
  66.  
  67.  
  68. class Board:
  69. pieces = [[]]
  70. message = ""
  71. board_number = 0
  72.  
  73. def __init__(self, pieces):
  74. global board_count
  75. self.pieces = pieces
  76. self.board_number = board_count
  77. board_count += 1
  78.  
  79. def score(self):
  80. def white():
  81. out = 0
  82. for row in self.pieces:
  83. for piece in row:
  84. if piece is not None:
  85. if piece.is_white:
  86. out += 1
  87. return out
  88.  
  89. def black():
  90. out = 0
  91. for row in self.pieces:
  92. for piece in row:
  93. if piece is not None:
  94. if not piece.is_white:
  95. out += 1
  96. return out
  97.  
  98. return white() - black()
  99.  
  100. def apply_move(self, move):
  101. assert (is_valid(self, move))
  102. piece = self.pieces[move.start_y][move.start_x]
  103. self.pieces[move.start_y][move.start_x] = None
  104. self.pieces[move.end_y][move.end_x] = piece
  105. if is_taking_piece(move):
  106. middle_x = (move.start_x + move.end_x) / 2
  107. middle_y = (move.start_y + move.end_y) / 2
  108. self.pieces[middle_y][middle_x] = None
  109. promote_pieces(self)
  110.  
  111. def render(self):
  112. global window, selected_square_y, selected_square_x
  113. window.erase()
  114. for y, row in enumerate(self.pieces):
  115. for x, piece in enumerate(row):
  116. if piece is None:
  117. if x == selected_square_x and y == selected_square_y:
  118. window.addstr(y, 2 * x, " ", curses.color_pair(blue_on_green))
  119. elif (y + x) % 2 == 1:
  120. window.addstr(y, 2 * x, " ", curses.color_pair(blue_on_black))
  121. else:
  122. window.addstr(y, 2 * x, " ", curses.color_pair(blue_on_white))
  123. elif piece.is_white:
  124. piece_name = " o"
  125. if piece.is_king:
  126. piece_name = "ko"
  127. window.addstr(y, 2 * x, piece_name, curses.color_pair(white_on_black))
  128. if x == selected_square_x and y == selected_square_y:
  129. window.addstr(y, 2 * x, piece_name, curses.color_pair(white_on_green))
  130. elif not piece.is_white:
  131. piece_name = " x"
  132. if piece.is_king:
  133. piece_name = "kx"
  134. window.addstr(y, 2 * x, piece_name, curses.color_pair(blue_on_black))
  135. if x == selected_square_x and y == selected_square_y:
  136. window.addstr(y, 2 * x, piece_name, curses.color_pair(blue_on_green))
  137. window.addstr(9, 0, self.message)
  138. window.refresh()
  139. # time.sleep(0.1)
  140.  
  141. def __str__(self):
  142. out = "["
  143. for row in self.pieces:
  144. out += "["
  145. for piece in row:
  146. out += ','
  147. out += piece.__str__()
  148. out += "]\n"
  149. out += "]"
  150. return out
  151.  
  152. def better_str(self):
  153. out = "["
  154. for row in self.pieces:
  155. out += "["
  156. for piece in row:
  157. out += ','
  158. if piece is None:
  159. out += " "
  160. else:
  161. out += piece.better_str()
  162. out += "]\n"
  163. out += "]"
  164. return out
  165.  
  166.  
  167. def is_taking_piece(move):
  168. if abs(move.end_x - move.start_x) == 2 and abs(move.end_y - move.start_y) == 2:
  169. return True
  170. return False
  171.  
  172.  
  173. def is_valid(board, move):
  174. # in my version of checkers pieces move diagonally by one piece
  175. # or take by moving 2 squares diagonally
  176. # kings can take backwards
  177. piece = board.pieces[move.start_y][move.start_x] # gets the piece being moved
  178. if piece is None:
  179. return False # move is not valid since there is no piece
  180.  
  181. def is_direction_correct():
  182. if piece.is_king:
  183. return True # kings can move in any direction they want as long as its diagonal
  184. if piece.is_white:
  185. # white pieces start at the bottom, so they have to move up unless they're king
  186. if move.start_y <= move.end_y:
  187. return False
  188. return True
  189. elif not piece.is_white:
  190. if move.start_y >= move.end_y:
  191. return False
  192. return True
  193. else:
  194. # the piece is nether white nor black. This can't be right
  195. assert False
  196.  
  197. def is_diagonal():
  198. if abs(move.end_x - move.start_x) == 1 and abs(move.end_y - move.start_y) == 1:
  199. return True
  200. elif abs(move.end_x - move.start_x) == 2 and abs(move.end_y - move.start_y) == 2:
  201. return True
  202. return False
  203.  
  204. def is_valid_take():
  205. middle_piece_x = (move.end_x + move.start_x) / 2
  206. middle_piece_y = (move.end_y + move.start_y) / 2
  207. middle_piece = board.pieces[middle_piece_y][middle_piece_x]
  208. if middle_piece is None:
  209. return False # you can't take nothing
  210. if piece.is_white:
  211. if middle_piece.is_white:
  212. return False # you can't take your own piece
  213. else:
  214. if not middle_piece.is_white:
  215. return False
  216. return True
  217.  
  218. def is_destination_empty():
  219. destination = board.pieces[move.end_y][move.end_x]
  220. if destination == None:
  221. return True
  222. return False
  223.  
  224. def is_destination_on_board():
  225. if move.end_x < 8 and move.end_y < 8:
  226. if move.end_x >= 0 and move.end_y >= 0:
  227. return True
  228. return False
  229.  
  230. if not is_destination_on_board():
  231. return False
  232. if not is_direction_correct():
  233. return False
  234. if not is_diagonal():
  235. return False
  236. if not is_destination_empty():
  237. return False
  238. if is_taking_piece(move):
  239. if not is_valid_take():
  240. return False
  241. return True
  242.  
  243.  
  244. def white_win_check():
  245. def is_white_winning():
  246. for row in main_board.pieces:
  247. for piece in row:
  248. if piece is not None and not piece.is_white:
  249. return False
  250. return True
  251.  
  252. if is_white_winning():
  253. curses.endwin()
  254. print "white wins"
  255.  
  256.  
  257. def black_win_check():
  258. def is_black_winning():
  259. for row in main_board.pieces:
  260. for piece in row:
  261. if piece is not None and piece.is_white:
  262. return False
  263. return True
  264.  
  265. if is_black_winning():
  266. curses.endwin()
  267. print "black wins"
  268.  
  269.  
  270. def promote_pieces(board):
  271. for x,piece in enumerate(board.pieces[0]):
  272. if piece is not None and piece.is_white:
  273. piece.is_king = True
  274. # print "promoting:" + str(x)
  275. for x,piece in enumerate(board.pieces[7]):
  276. if piece is not None and not piece.is_white:
  277. piece.is_king = True
  278. # print "promoting:" + str(x)
  279.  
  280.  
  281. def position_evaluate(board, depth, is_white_moving):
  282. def not_slow_copy(array):
  283. out = []
  284. for row in array:
  285. out.append(copy.deepcopy(row))
  286. return out
  287.  
  288. if depth == 0:
  289. return board.score(), None
  290. else:
  291. boards = []
  292. for y, row in enumerate(board.pieces):
  293. for x, piece in enumerate(row):
  294. if piece is None:
  295. continue
  296. if piece.is_white != is_white_moving:
  297. continue
  298. moves = [
  299. Move(x, y, x + 1, y + 1),
  300. Move(x, y, x + 1, y - 1),
  301. Move(x, y, x - 1, y + 1),
  302. Move(x, y, x - 1, y - 1),
  303. Move(x, y, x + 2, y + 2),
  304. Move(x, y, x + 2, y - 2),
  305. Move(x, y, x - 2, y + 2),
  306. Move(x, y, x - 2, y - 2)
  307. ]
  308. for move in moves:
  309. if is_valid(board, move):
  310. board_copy = Board(not_slow_copy(board.pieces))
  311. board_copy.apply_move(move)
  312. boards.append((board_copy, move))
  313. dot_file.write(
  314. "a" + str(board_copy.board_number) + " [label =\"" + board_copy.better_str() + "\"];")
  315. dot_file.write("a" + str(board.board_number) + " -> a" + str(board_copy.board_number) + ";")
  316. evaluated_moves = []
  317. for board, move in boards:
  318. eval, previous_move = position_evaluate(
  319. board,
  320. depth - 1,
  321. not is_white_moving
  322. )
  323. evaluated_moves.append([eval, (move, previous_move)])
  324. if is_white_moving:
  325. max = [-100000000, None]
  326. for evaluated_move in evaluated_moves:
  327. if evaluated_move[0] > max[0]:
  328. max = evaluated_move
  329. return max
  330. else:
  331. min = [100000000, None]
  332. for evaluated_move in evaluated_moves:
  333. if evaluated_move[0] < min[0]:
  334. min = evaluated_move
  335. return min
  336.  
  337.  
  338. def main_loop():
  339. def get_key_presses():
  340. global selected_square_y, selected_square_x
  341. while True:
  342. key = int(window.getch())
  343. if key == 10:
  344. return None
  345. elif key == curses.KEY_UP:
  346. selected_square_y -= 1
  347. elif key == curses.KEY_DOWN:
  348. selected_square_y += 1
  349. elif key == curses.KEY_LEFT:
  350. selected_square_x -= 1
  351. elif key == curses.KEY_RIGHT:
  352. selected_square_x += 1
  353. main_board.render()
  354.  
  355. def ask_for_white_piece():
  356. white_win_check()
  357. black_win_check()
  358. main_board.message = "Please select a white piece"
  359. window.refresh()
  360. get_key_presses()
  361. ask_for_white_move(selected_square_x, selected_square_y)
  362.  
  363. def ask_for_white_move(x, y):
  364. main_board.message = "Please select the square you want your piece to go to"
  365. window.refresh()
  366. get_key_presses()
  367. move = Move(x, y, selected_square_x, selected_square_y)
  368. if is_valid(main_board, move):
  369. main_board.apply_move(move)
  370. do_black_move()
  371. else:
  372. main_board.message = "Invalid Move"
  373. main_board.render()
  374. window.refresh()
  375. time.sleep(2)
  376. ask_for_white_piece()
  377.  
  378. def ask_for_black_piece():
  379. main_board.message = "Please select a black piece"
  380. window.refresh()
  381. get_key_presses()
  382. ask_for_black_move(selected_square_x, selected_square_y)
  383.  
  384. def ask_for_black_move(x, y):
  385. main_board.message = "Please select the square you want your piece to go to"
  386. window.refresh()
  387. get_key_presses()
  388. move = Move(x, y, selected_square_x, selected_square_y)
  389. if is_valid(main_board, move):
  390. main_board.apply_move(move)
  391. ask_for_white_piece()
  392. else:
  393. main_board.message = "Invalid Move"
  394. window.refresh()
  395. time.sleep(0.5)
  396. ask_for_black_piece()
  397.  
  398. def do_black_move():
  399. eval, move = position_evaluate(main_board, 4, False)
  400. if move is None:
  401. curses.endwin()
  402. print "stalemate detected"
  403. move = move[0]
  404. assert (is_valid(main_board, move))
  405. main_board.apply_move(move)
  406. ask_for_white_piece()
  407.  
  408. global main_board, window
  409. while True:
  410. main_board.render()
  411. ask_for_white_piece()
  412.  
  413.  
  414. white_on_black = 1
  415. white_on_white = 2
  416. white_on_green = 5
  417. blue_on_white = 3
  418. blue_on_black = 4
  419. blue_on_green = 6
  420. screen = None
  421. text_window = None
  422.  
  423.  
  424. def main():
  425. global main_board, window, screen, text_window
  426. main_board = Board([[None, Piece(False), None, Piece(False), None, Piece(False), None, Piece(False)],
  427. [Piece(False), None, Piece(False), None, Piece(False), None, Piece(False), None],
  428. [None, Piece(False), None, Piece(False), None, Piece(False), None, Piece(False)],
  429. [None, None, None, None, None, None, None, None],
  430. [None, None, None, None, None, None, None, None],
  431. [Piece(True), None, Piece(True), None, Piece(True), None, Piece(True), None],
  432. [None, Piece(True), None, Piece(True), None, Piece(True), None, Piece(True)],
  433. [Piece(True), None, Piece(True), None, Piece(True), None, Piece(True), None]
  434. ])
  435. screen = curses.initscr()
  436. curses.start_color()
  437. curses.use_default_colors()
  438. curses.init_pair(white_on_black, curses.COLOR_WHITE, curses.COLOR_BLACK)
  439. curses.init_pair(white_on_white, curses.COLOR_YELLOW, curses.COLOR_WHITE)
  440. curses.init_pair(blue_on_white, curses.COLOR_BLUE, curses.COLOR_WHITE)
  441. curses.init_pair(blue_on_black, curses.COLOR_BLUE, curses.COLOR_BLACK)
  442. curses.init_pair(blue_on_green, curses.COLOR_BLUE, curses.COLOR_GREEN)
  443. curses.init_pair(white_on_green, curses.COLOR_WHITE, curses.COLOR_GREEN)
  444. curses.curs_set(0)
  445. window = curses.newwin(0, 0)
  446. text_window = curses.newwin(9, 0)
  447. window.keypad(1)
  448. window.nodelay(1)
  449. main_loop()
  450.  
  451.  
  452. curses.wrapper(main())
  453.  
  454. #main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement