# TODO: The bar is just for show at the moment. Home doesn't work either. # TODO: An issue with the bouncing back things. It appears to do the move and then # it doesn't properly restore the buckets to where they should be. import random import pygame import threading from board import Board import numpy as np import time # --- constants --- (UPPER_CASE names) class Board_painter: def __init__(self): self.SCREEN_WIDTH = 1050 self.SCREEN_HEIGHT = 400 self.SPACING = 83.333 #BLACK = ( 0, 0, 0) #242 209 107 self.SAND = (242, 209, 107) self.GREEN_FILT = (0,102,0) self.WHITE = (255, 255, 255) self.RED = (255, 0, 0) self.SALMON = (250,128,114) self.BLACK = (0,0,0) self.BROWN = (160,82,45) self.LIGHT_GREY = (220,220,220) self.num_pieces = 15 self.FPS = 999 cen = self.SPACING/2 - 11 t = 5*self.SPACING - cen-22 m = 7*self.SPACING+50 - cen-22 self.STARTING_IDX_P1 = [[cen,0], [cen, 30], [cen, 60], [cen, 90], [cen,120], [self.SCREEN_WIDTH-cen-22, 0], [self.SCREEN_WIDTH-cen-22, 30], [t, 378],[t,348],[t,318],[m, 378], [m,348],[m,318],[m,288],[m,258]] self.STARTING_IDX_P2 = [[cen, 378], [cen, 348], [cen, 318], [cen, 288], [cen, 258], [self.SCREEN_WIDTH-cen-22, 378], [self.SCREEN_WIDTH-cen-22, 348], [t, 0], [t, 30], [t, 60], [m, 0], [m,30],[m,60],[m,90],[m,120]] pygame.init() self.screen = pygame.display.set_mode((self.SCREEN_WIDTH, self.SCREEN_HEIGHT)) #screen_rect = screen.get_rect() pygame.display.set_caption("Backgammon") self.all_rects = {-1 : [], 1 : []} for p in [-1,1]: if p == -1: for idx in self.STARTING_IDX_P1: self.all_rects[p] += [pygame.rect.Rect(idx[0],idx[1], 22, 22)] if p == 1: for idx in self.STARTING_IDX_P2: self.all_rects[p] += [pygame.rect.Rect(idx[0],idx[1], 22, 22)] # for i in range(num_pieces): # x = x+20 # all_rects[p] += [pygame.rect.Rect(x,y, 22, 22)] # x = 100 # y += 100 self.all_drag = {-1 : [], 1 : []} self.all_drag[-1] += [False]*self.num_pieces self.all_drag[1] += [False]*self.num_pieces self.all_off = {-1 : [], 1 : []} self.all_off[-1] += [[0,0]]*self.num_pieces self.all_off[1] += [[0,0]]*self.num_pieces self.is_true = False self.clock = pygame.time.Clock() self.buckets = [[0,0],[5,-1],[0,0],[0,0],[0,0],[3,1],[0,0],[5,1],[0,0],[0,0],[0,0],[0,0],[2,-1],[5,1],[0,0],[0,0],[0,0],[3,-1],[0,0],[5,-1],[0,0],[0,0],[0,0],[0,0],[2,1],[0,0]] self.running = True self.player = -1 self.roll = [random.randrange(1, 7), random.randrange(1, 7)] print("initial_roll:", self.roll) self.from_board = None self.from_buckets = [x for x in self.buckets] self.from_locat = None self.total_moves = 0 def switch_player(self): self.player *= -1 print("CHANGED PLAYER!") def gen_buckets_from_board(self, board): meh = [] for i in range(13,25): pin = board[i] # print(pin) meh.append([abs(pin), np.sign(pin)]) for i in range(1,13): pin = board[i] meh.append([abs(pin), np.sign(pin)]) return meh def gen_board_from_buckets(self, buckets): board = [] board.append(buckets[0]) for i in range(-2,-14,-1): board.append(buckets[i]) for i in range(1,13): board.append(buckets[i]) board.append(buckets[25]) board = [x*y for x,y in board] return board def move_legal(self, from_board, buckets, roll): board = self.gen_board_from_buckets(buckets) legal_states = Board.calculate_legal_states(from_board, self.player, roll) # print(legal_states) if board in [list(state) for state in list(legal_states)]: return True return False def find_pin(self, pos): SPACING = self.SPACING x,y = pos x -= 50 if x > 550 else 0 if y < 175: pin = (13 + int(x / SPACING)) idx = 1+int(x / SPACING) elif y > 225: pin = (12 - int(x / SPACING)) idx = 13+ int(x / SPACING) return pin, idx # Find the y position based on the chosen pin def calc_pos(self, buckets, chosen): amount = buckets[chosen][0] print(chosen) SPACING = self.SPACING if chosen == 0: x = 525 y = 350 elif chosen == 26: x = 525 y = 50 else: if chosen > 12: # print("Amount at pin:", amount) y = 378 - (30 * amount) chosen -= 12 x = (SPACING*(chosen-1))+(SPACING/2) x += 50 if x > 500 else 0 else: y = 30 * amount x = (SPACING*(chosen-1))+(SPACING/2) x += 50 if x > 500 else 0 return x,y def calc_move_sets(self, from_board, roll, player): # board = self.gen_board_from_buckets(buckets) board = from_board sets = [] total = 0 print("board!:",board) for r in roll: # print("Value of r:",r) sets.append([Board.calculate_legal_states(board, player, [r,0]), r]) total += r sets.append([Board.calculate_legal_states(board, player, [total,0]), total]) return sets def calc_turn(self): player = self.player if self.total_moves == 0: return player * -1 return player def handle_move(self, from_board, buckets, roll, player): board = self.gen_board_from_buckets(buckets) # print("Cur board:",board) sets = self.calc_move_sets(from_board, roll, player) for idx, board_set in enumerate(sets): board_set[0] = list(board_set[0]) # print("My board_set:",board_set) if board in [list(c) for c in board_set[0]]: self.total_moves -= board_set[1] if idx < 2: # print("Roll object:",self.roll) self.roll[idx] = 0 else: self.roll = [0,0] break print("Total moves left:",self.total_moves) # while running: def paint_board(self): # - events - if self.player != self.calc_turn(): self.switch_player() self.roll = [random.randrange(1, 7), random.randrange(1, 7)] self.total_moves = self.roll[0] + self.roll[1] print("Player:",self.player,"rolled:",self.roll) player = self.player rectangles_drag = self.all_drag[player] rectangles = self.all_rects[player] offsets = self.all_off[player] buckets = self.buckets for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: meh = [rect.collidepoint(event.pos) for rect in rectangles] if any(meh): is_true = np.where(meh)[0][0] if any(meh): # print("GETTING CALLED") rectangles_drag[is_true] = True mouse_x, mouse_y = event.pos # Need this to be a deepcopy :< self.from_buckets = [] for x in buckets: tmp = [] for y in x: tmp.append(y) self.from_buckets.append(tmp) self.from_board = [x for x in self.gen_board_from_buckets(buckets)] # print("From board in mousedown:", from_board) pin, idx = self.find_pin(event.pos) from_pin = pin buckets[idx][0] -= 1 if buckets[idx][0] == 0: buckets[idx][1] = 0 offsets[is_true][0] = rectangles[is_true].x - mouse_x offsets[is_true][1] = rectangles[is_true].y - mouse_y self.from_locat = [rectangles[is_true].x, rectangles[is_true].y] elif event.type == pygame.MOUSEBUTTONUP: if event.button == 1: meh = [rect.collidepoint(event.pos) for rect in rectangles] if any(meh): is_true = np.where(meh)[0][0] pin, idx = self.find_pin(event.pos) x, y = self.calc_pos(buckets,idx) # Need to take care of bar stuff :< if (buckets[idx][1] == player*-1) and buckets[idx][0] == 1: to_idx = 0 if buckets[idx][1] == 1 else 25 enemy_rects = self.all_rects[player*-1] # Have some check if we're looking for either rects in the bottom or top, # instead of having both here neg_tester = [rect.collidepoint(x,y-30) for rect in enemy_rects] pos_tester = [rect.collidepoint(x,y+40) for rect in enemy_rects] print("Neg tester:",neg_tester) print("Pos tester:",pos_tester) if any(neg_tester): enemy = np.where(neg_tester)[0][0] elif any(pos_tester): enemy = np.where(pos_tester)[0][0] buckets[to_idx][0] += 1 buckets[to_idx][1] = buckets[idx][1] bar_x, bar_y = self.calc_pos(buckets, to_idx) enemy_rects[enemy].x = bar_x enemy_rects[enemy].y = bar_y buckets[idx][0] = 0 print("In here"*20) pin, idx = self.find_pin(event.pos) x, y = self.calc_pos(buckets,idx) buckets[idx][0] += 1 buckets[idx][1] = player # print(self.from_board) # print("To :",self.gen_board_from_buckets(buckets)) # print(move_legal(from_board, buckets, [1,2])) print("from board:",self.from_board) # if self.move_legal(self.from_board, buckets, self.roll): pot_board = self.gen_board_from_buckets(buckets) sets = self.calc_move_sets(self.from_board, self.roll, player) print("potential board:",pot_board) # print("board:",pot_board) truth_values = [] for t in sets: b = [list(c) for c in list(t)[0]] if pot_board in list(b): truth_values.append(pot_board in list(b)) print("Truth values:",truth_values) if any(truth_values): self.handle_move(self.from_board, buckets, self.roll, player) # print("From:",self.gen_board_from_buckets(self.from_buckets)) # print("WOHO!"*10) rectangles_drag[is_true] = False rectangles[is_true].x = x rectangles[is_true].y = y else: # print("From:",self.gen_board_from_buckets(self.from_buckets)) self.buckets = [] for x in self.from_buckets: tmp = [] for y in x: tmp.append(y) self.buckets.append(tmp) rectangles_drag[is_true] = False rectangles[is_true].x = self.from_locat[0] rectangles[is_true].y = self.from_locat[1] # print("End :",self.gen_board_from_buckets(buckets)) elif event.type == pygame.MOUSEMOTION: if any(rectangles_drag): is_true = np.where(rectangles_drag)[0][0] mouse_x, mouse_y = event.pos rectangles[is_true].x = mouse_x + offsets[is_true][0] rectangles[is_true].y = mouse_y + offsets[is_true][1] self.screen.fill(self.GREEN_FILT) # pygame.draw.polygon(screen, (RED), [[0, 0], [50,0],[25,100]], 2) color = self.LIGHT_GREY x = 0 y = 150 # for _ in range(2): for i in range(12): if x < 500 and x+self.SPACING > 500: x = 550 color = self.SALMON if color == self.LIGHT_GREY else self.LIGHT_GREY pygame.draw.polygon(self.screen, color, [[x, 0], [x+self.SPACING, 0], [(2*x+self.SPACING)/2, y]]) x += self.SPACING # y += 50 x = 0 y = 250 # for _ in range(2): color = self.SALMON if color == self.LIGHT_GREY else self.LIGHT_GREY for i in range(12): if x < 500 and x+self.SPACING > 500: x = 550 color = self.SALMON if color == self.LIGHT_GREY else self.LIGHT_GREY pygame.draw.polygon(self.screen, color, [[x, 400], [x+self.SPACING, 400], [(2*x+self.SPACING)/2, y]]) x += self.SPACING # print(gen_board_from_buckets(buckets)) pygame.draw.rect(self.screen, self.BROWN, pygame.rect.Rect((500, 0, 50, 400))) for p in [-1,1]: for rect in self.all_rects[p]: pygame.draw.rect(self.screen, self.RED if p == -1 else self.BLACK, rect) pygame.display.flip() # - constant game speed / FPS - self.clock.tick(self.FPS) def test(self): while True: self.paint_board() b = Board_painter() b.test() # class myThread (threading.Thread): # def __init__(self, threadID, name, counter): # threading.Thread.__init__(self) # self.threadID = threadID # self.name = name # self.counter = counter # def run(self, function): # print ("Starting " + self.name) # function() # print ("Exiting " + self.name) # def change_player(): # while True: # time.sleep(5) # b.switch_player([1,2]) # def keep_painting(): # while True: # b.paint_board() # # Create new threads # thread2 = myThread( keep_painting() ) # thread1 = myThread( change_player() ) # # Start new Threads # thread1.start() # thread2.start() # thread1.join() # thread2.join() # print ("Exiting Main Thread") # # - end - # pygame.quit()