def tuple_to_bbm(move): """converte tupla de x, y para bit em bitboard""" bbm = i64(1) << i64(63) x = i64(move[0]) y = i64(move[1]) bbm >>= ((x-ONE) << 3) # x << 3 eh igual a x * 8 bbm >>= (y-ONE) return bbm
def __init__(self, color): self.color = color self.fixImports() self.all_corners = ( ONE << i64(63), # top left ONE << i64(56), # top right ONE << i64(7), # lower left ONE) # lower right
def print_bbn(bbn): """imprime um numero 64 bits em bitboard 8x8""" mask = i64(1) << i64(63) for i in range(8): line = "" for j in range(8): line += ("1" if bbn & mask else "0") mask >>= i64(1) print(line)
def empty_nbors(bb): """retorna as posicoes vazias vizinhas a pecas minhas e pecas do inimigo""" me_nbors = i64(0) op_nbors = i64(0) for direction in next_move_directions: me_nbors |= (direction(bb.me) & empty) op_nbors |= (direction(bb.op) & empty) return me_nbors, op_nbors
def h_stability(bb): """ estabilidade de cada jogador (isto e, nr. de pecas de cada jogador que nao pode mais ser revertida, e nr. de pecas de cada jogador que pode ser revertida no proximo turno)""" me_moves_raw = find_moves(bb) op_moves_raw = find_moves(bb.change_player_c()) me_unstables_raw = i64(0) op_unstables_raw = i64(0) moves_iter = bits_iter(me_moves_raw | op_moves_raw) #unstables for at in moves_iter: if at & me_moves_raw: for next_dir in next_move_directions: walk = next_dir(at) line = i64(0) while (walk & bb.op): line |= walk walk = next_dir(walk) if (walk & bb.me): op_unstables_raw |= line else: for next_dir in next_move_directions: walk = next_dir(at) line = i64(0) while (walk & bb.me): line |= walk walk = next_dir(walk) if (walk & bb.op): me_unstables_raw |= line me_unstables = bitcount(me_unstables_raw) op_unstables = bitcount(op_unstables_raw) me_stables = 0.0 op_stables = 0.0 occupied = bb.me | bb.op me_possible_stables_iter = bits_iter(bb.me & ~me_unstables_raw) op_possible_stables_iter = bits_iter(bb.op & ~op_unstables_raw) for at in me_possible_stables_iter: if (masks[at] | occupied) == occupied: me_stables += 1 elif all(( (mask_left|mask_right|occupied) == occupied or (mask_left & bb.me) == mask_left or (mask_right & bb.me) == mask_right) for mask_left, mask_right in masks_dirs[at]): me_stables += 1 for at in op_possible_stables_iter: if (masks[at] | occupied) == occupied: op_stables += 1 elif all(( (mask_left|mask_right|occupied) == occupied or (mask_left & bb.op) == mask_left or (mask_right & bb.op) == mask_right) for mask_left, mask_right in masks_dirs[at]): op_stables += 1 return fake_norm(me_stables+op_unstables, op_stables+me_unstables)
def h_potential_movements_est(bb): """ numero de movimentos potencial estimado (isto e, nr. de casas vazias vizinhas a pecas inimigas )""" empty = bb.get_empty() me_frontier = i64(0) op_frontier = i64(0) for dir_next in next_move_directions: me_frontier |= (dir_next(empty) & bb.me) op_frontier |= (dir_next(empty) & bb.op) return fake_norm(bitcount(op_frontier), bitcount(me_frontier))
def h_stability(bb): """ estabilidade de cada jogador (isto e, nr. de pecas de cada jogador que nao pode mais ser revertida )""" me_moves_raw = find_moves(bb) op_moves_raw = find_moves(bb.change_player_c()) me_unstables_raw = i64(0) op_unstables_raw = i64(0) moves_iter = bits_iter(me_moves_raw | op_moves_raw) #unstables at = i64(1) for at in moves_iter: if at & me_moves_raw: for next_dir in next_move_directions: walk = next_dir(at) line = i64(0) while (walk & bb.op): line |= walk walk = next_dir(walk) if (walk & bb.me): op_unstables_raw |= line else: for next_dir in next_move_directions: walk = next_dir(at) line = i64(0) while (walk & bb.me): line |= walk walk = next_dir(walk) if (walk & bb.op): me_unstables_raw |= line me_unstables = bitcount(me_unstables_raw) op_unstables = bitcount(op_unstables_raw) me_stables = 0 op_stables = 0 occupied = bb.me | bb.op all_unstables_raw = me_unstables_raw | op_unstables_raw possible_stables_iter = bits_iter(occupied & ~all_unstables_raw) for at in possible_stables_iter: if (masks[at] | occupied) == occupied: if at & bb.me: me_stables += 1 else: op_stables += 1 return fake_norm(me_stables + op_unstables, op_stables + me_unstables)
def bbm_to_tuple(bbm): """converte bit em bitboard para tupla de x, y""" i = 0 j = 0 movel = i64(bbm) movec = i64(bbm) while(movel): movel = next_up(movel) i += 1 while(movec): movec = next_left(movec) j += 1 return i, j
def print_pov(bb): """imprime um tabuleiro do meu ponto de vista""" mask = i64(1) << i64(63) for i in range(8): line = "" for j in range(8): if (bb.me & mask): line += 'M' elif (bb.op & mask): line += 'O' else: line += '.' mask >>= i64(1) print(line)
def bb_from(board, color): """converte uma board da lib do victorlcampos em uma BitBoard""" me = i64(0) op = i64(0) color_op = board._opponent(color) n = i64(64) for i in range(1, 9): for j in range(1, 9): n -= ONE if (board.get_square_color(i,j) == color): me |= ONE << n elif (board.get_square_color(i,j) == color_op): op |= ONE << n return BitBoard(me, op)
def precalc_mask_stability(): """calcula mascaras binarias pra auxiliar ao decidir se alguma peca eh estavel""" ONE = i64(1) THREE = i64(3) mymasks = dict() mymasks_dirs = dict() for ni in range(8): for nj in range(8): i = i64(ni) j = i64(nj) at = (ONE << j) << (i << THREE) if ((at | mask_t_corners) == mask_t_corners): mymasks[at] = at mymasks_dirs[at] = tuple() elif ((at | mask_t_up) == mask_t_up): mymasks[at] = i64(0xFF00000000000000) mymasks_dirs[at] = ((mask_h << (i << THREE)) & ~(at-ONE), (mask_h << (i << THREE)) & (at-ONE)), elif ((at | mask_t_left) == mask_t_left): mymasks[at] = i64(0x8080808080808080) mymasks_dirs[at] = ((mask_v << j) & ~(at-ONE), (mask_v << j) & (at-ONE)), elif ((at | mask_t_right) == mask_t_right): mymasks[at] = i64(0x0101010101010101) mymasks_dirs[at] = ((mask_v << j) & ~(at-ONE), (mask_v << j) & (at-ONE)), elif ((at | mask_t_down) == mask_t_down): mymasks[at] = i64(0x00000000000000FF) mymasks_dirs[at] = ((mask_h << (i << THREE)) & ~(at-ONE), (mask_h << (i << THREE)) & (at-ONE)), else: mask_ij = (mask_h << (i << THREE)) | (mask_v << j) mymasks_dirs[at] = ((mask_h << (i << THREE)) & ~(at-ONE), (mask_h << (i << THREE)) & (at-ONE)), ((mask_v << j) & ~(at-ONE), (mask_v << j) & (at-ONE)) if (i > j): mask_ij |= (mask_d1 << ((i - j) << THREE)) mymasks_dirs[at] += ((mask_d1 << ((i - j) << THREE)) & ~(at-ONE), (mask_d1 << ((i - j) << THREE)) & (at-ONE)), else: mask_ij |= (mask_d1 >> ((j - i) << THREE)) mymasks_dirs[at] += ((mask_d1 >> ((j - i) << THREE)) & ~(at-ONE), (mask_d1 >> ((j - i) << THREE)) & (at-ONE)), d = i64(7) - i if (d > j): mask_ij |= (mask_d2 >> ((d - j) << THREE)) mymasks_dirs[at] += ((mask_d2 >> ((d - j) << THREE)) & ~(at-ONE), (mask_d2 >> ((d - j) << THREE)) & (at-ONE)), else: mask_ij |= (mask_d2 << ((j - d) << THREE)) mymasks_dirs[at] += ((mask_d2 << ((j - d) << THREE)) & ~(at-ONE), (mask_d2 << ((j - d) << THREE)) & (at-ONE)), mymasks[at] = mask_ij return mymasks, mymasks_dirs
def __init__(self, color): self.color = color self.fixImports() self.dangerous = (ONE << i64(63), # top left ONE << i64(56), # top right ONE << i64(7), # lower left ONE, # lower right ONE << i64(54), ONE << i64(49), ONE << i64(14), ONE << i64(9))
def __init__(self, color,p1,p2,p3): self.color = color self.fixImports() self.dangerous_raw = i64(0) self.dangerous = (ONE << i64(63), # top left ONE << i64(56), # top right ONE << i64(7), # lower left ONE, # lower right ONE << i64(54), ONE << i64(49), ONE << i64(14), ONE << i64(9)) self.myweights = (tuple(p1), tuple(p2), tuple(p3)) for at in self.dangerous[4:]: self.dangerous_raw |= at
def __init__(self, color): self.color = color self.fixImports() self.dangerous_raw = i64(0) self.dangerous = ( ONE << i64(63), # top left ONE << i64(56), # top right ONE << i64(7), # lower left ONE, # lower right ONE << i64(54), ONE << i64(49), ONE << i64(14), ONE << i64(9)) for at in self.dangerous[4:]: self.dangerous_raw |= at if (color == '@'): self.myweights = self.myweightsPreta elif (color == 'o'): self.myweights = self.myweightsBranca
def play(self, move): """aplica um movimento na bitboard""" empty = self.get_empty() walk = (move << SIZE) & BB_UP line = i64(0) while (walk & self.op): line |= walk walk = (walk << SIZE) & BB_UP if (walk & self.me): self.op &= ~line self.me |= line walk = (move >> SIZE) & BB_DOWN line = i64(0) while (walk & self.op): line |= walk walk = (walk >> SIZE) & BB_DOWN if (walk & self.me): self.op &= ~line self.me |= line walk = (move << ONE) & BB_LEFT line = i64(0) while (walk & self.op): line |= walk walk = (walk << ONE) & BB_LEFT if (walk & self.me): self.op &= ~line self.me |= line walk = (move >> ONE) & BB_RIGHT line = i64(0) while (walk & self.op): line |= walk walk = (walk >> ONE) & BB_RIGHT if (walk & self.me): self.op &= ~line self.me |= line walk = (move << SIZEP1) & BB_UP_LEFT line = i64(0) while (walk & self.op): line |= walk walk = (walk << SIZEP1) & BB_UP_LEFT if (walk & self.me): self.op &= ~line self.me |= line walk = (move << SIZEM1) & BB_UP_RIGHT line = i64(0) while (walk & self.op): line |= walk walk = (walk << SIZEM1) & BB_UP_RIGHT if (walk & self.me): self.op &= ~line self.me |= line walk = (move >> SIZEM1) & BB_DOWN_LEFT line = i64(0) while (walk & self.op): line |= walk walk = (walk >> SIZEM1) & BB_DOWN_LEFT if (walk & self.me): self.op &= ~line self.me |= line walk = (move >> SIZEP1) & BB_DOWN_RIGHT line = i64(0) while (walk & self.op): line |= walk walk = (walk >> SIZEP1) & BB_DOWN_RIGHT if (walk & self.me): self.op &= ~line self.me |= line self.me |= move return self
def __init__(self, me, op): self.me = i64(me) self.op = i64(op)
# -*- coding: cp1252 -*- from models.players.bitboard import * from views.console_board_view import ConsoleBoardView from math import exp from numpy import uint64 as i64 from timeit import default_timer as timer import csv inf_pos = float("inf") inf_neg = -inf_pos mask_h = i64(0x00000000000000FF) # horizontal mask_v = i64(0x0101010101010101) # vertical mask_d1 = i64(0x8040201008040201) # diagonal up-left -> down-right mask_d2 = i64(0x0102040810204080) # diagonal up-right -> down-left mask_t_up = i64(0x7E00000000000000) mask_t_left = i64(0x0080808080808000) mask_t_right = i64(0x0001010101010100) mask_t_down = i64(0x000000000000007E) mask_t_corners = i64(0x8100000000000081) ONE = i64(1) THREE = i64(3) def print_mask(m): for x in ['{0:064b}'.format(m)[i:i+8] for i in range(0, 64, 8)]: print(x) masks = None masks_dirs = None
def find_moves(bb): """acha movimentos possiveis para mim""" me = bb.me op = bb.op empty = bb.get_empty() moves = i64(0) viable = op & BB_UPDOWN candidates = viable & (me << SIZE) candidates |= viable & (candidates << SIZE) candidates |= viable & (candidates << SIZE) candidates |= viable & (candidates << SIZE) candidates |= viable & (candidates << SIZE) candidates |= viable & (candidates << SIZE) moves |= empty & (candidates << SIZE) viable = op & BB_UPDOWN candidates = viable & (me >> SIZE) candidates |= viable & (candidates >> SIZE) candidates |= viable & (candidates >> SIZE) candidates |= viable & (candidates >> SIZE) candidates |= viable & (candidates >> SIZE) candidates |= viable & (candidates >> SIZE) moves |= empty & (candidates >> SIZE) viable = op & BB_LEFTRIGHT candidates = viable & (me << ONE) candidates |= viable & (candidates << ONE) candidates |= viable & (candidates << ONE) candidates |= viable & (candidates << ONE) candidates |= viable & (candidates << ONE) candidates |= viable & (candidates << ONE) moves |= empty & (candidates << ONE) viable = op & BB_LEFTRIGHT candidates = viable & (me >> ONE) candidates |= viable & (candidates >> ONE) candidates |= viable & (candidates >> ONE) candidates |= viable & (candidates >> ONE) candidates |= viable & (candidates >> ONE) candidates |= viable & (candidates >> ONE) moves |= empty & (candidates >> ONE) viable = op & BB_UPLEFTDOWNRIGHT candidates = viable & (me << SIZEP1) candidates |= viable & (candidates << SIZEP1) candidates |= viable & (candidates << SIZEP1) candidates |= viable & (candidates << SIZEP1) candidates |= viable & (candidates << SIZEP1) candidates |= viable & (candidates << SIZEP1) moves |= empty & (candidates << SIZEP1) viable = op & BB_UPRIGHTDOWNLEFT candidates = viable & (me << SIZEM1) candidates |= viable & (candidates << SIZEM1) candidates |= viable & (candidates << SIZEM1) candidates |= viable & (candidates << SIZEM1) candidates |= viable & (candidates << SIZEM1) candidates |= viable & (candidates << SIZEM1) moves |= empty & (candidates << SIZEM1) viable = op & BB_UPRIGHTDOWNLEFT candidates = viable & (me >> SIZEM1) candidates |= viable & (candidates >> SIZEM1) candidates |= viable & (candidates >> SIZEM1) candidates |= viable & (candidates >> SIZEM1) candidates |= viable & (candidates >> SIZEM1) candidates |= viable & (candidates >> SIZEM1) moves |= empty & (candidates >> SIZEM1) viable = op & BB_UPLEFTDOWNRIGHT candidates = viable & (me >> SIZEP1) candidates |= viable & (candidates >> SIZEP1) candidates |= viable & (candidates >> SIZEP1) candidates |= viable & (candidates >> SIZEP1) candidates |= viable & (candidates >> SIZEP1) candidates |= viable & (candidates >> SIZEP1) moves |= empty & (candidates >> SIZEP1) return moves
from numpy import uint64 as i64 from copy import deepcopy from models.move import Move from models.board import Board ZERO = i64(0) ONE = i64(1) TWO = i64(2) THREE = i64(3) FOUR = i64(4) SIZE = i64(8) SIZEM1 = i64(7) SIZEP1 = i64(9) BB_UP = i64(0xFFFFFFFFFFFFFF00) BB_DOWN = i64(0x00FFFFFFFFFFFFFF) BB_LEFT = i64(0xFEFEFEFEFEFEFEFE) BB_RIGHT = i64(0x7F7F7F7F7F7F7F7F) BB_UP_LEFT = i64(0xFEFEFEFEFEFEFE00) BB_UP_RIGHT = i64(0x7F7F7F7F7F7F7F00) BB_DOWN_LEFT = i64(0x00FEFEFEFEFEFEFE) BB_DOWN_RIGHT = i64(0x007F7F7F7F7F7F7F) BB_UPDOWN = BB_UP & BB_DOWN BB_LEFTRIGHT = BB_LEFT & BB_RIGHT BB_UPLEFTDOWNRIGHT = BB_UP_LEFT & BB_DOWN_RIGHT BB_UPRIGHTDOWNLEFT = BB_UP_RIGHT & BB_DOWN_LEFT def next_up(x): return (x << SIZE) & BB_UP def next_down(x):