Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import copy
- import colorama
- from colorama import Back, Fore, Style
- def is_valid(m):
- i, j = m
- return 0 <= i < 6 and 0 <= j < 6
- def is_free(state, tgt):
- if not is_valid(tgt):
- return False
- return state[tgt[0]][tgt[1]] == 0
- def get_moves(state, player, *, only_capture=False):
- res = []
- res2 = []
- mpl = player
- for i, row in enumerate(state):
- for j, x in enumerate(row):
- start = i, j
- if x * mpl > 0:
- if not only_capture:
- len = 1
- while True:
- m = i + len * mpl, j + len
- if is_valid(m) and is_free(state, m):
- res.append([start, m])
- else:
- break
- if abs(x) == 1:
- break
- len += 1
- len = 1
- while True:
- m = i + len * mpl, j - len
- if is_valid(m) and is_free(state, m):
- res.append([start, m])
- else:
- break
- if abs(x) == 1:
- break
- len += 1
- if abs(x) > 1:
- len = 1
- while True:
- m = i - len * mpl, j + len
- if is_valid(m) and is_free(state, m):
- res.append([start, m])
- else:
- break
- len += 1
- len = 1
- while True:
- m = i - len * mpl, j - len
- if is_valid(m) and is_free(state, m):
- res.append([start, m])
- else:
- break
- len += 1
- def try_capture(prefix, i0, j0):
- for dx, dy in [(-1, -1), (-1, 1), (1, -1), (1, 1)]:
- i1, j1 = i0, j0
- k = 0
- while is_valid((i1, j1)) and state[i1][j1] * x >= 0:
- i1 += dx
- j1 += dy
- k += 1
- if not is_valid((i1, j1)):
- continue
- if abs(x) == 1 and k > 1:
- continue
- ci, cj = i1, j1
- while True: # landing square
- i1 += dx
- j1 += dy
- if is_free(state, (i1, j1)):
- res2.append(prefix + [(i1, j1)])
- tmp = state[ci][cj]
- state[ci][cj] = 0
- try_capture(prefix + [(i1, j1)], i1, j1)
- state[ci][cj] = tmp
- else:
- break
- if abs(x) == 1:
- break
- try_capture([(i, j)], i, j)
- if res2:
- return res2
- return res
- eval_matrix2 = [
- [None, 0, None, 0, None, 1],
- [1, None, 1, None, 0, None],
- [None, 7, None, 6, None, 4],
- [13, None, 9, None, 11, None],
- [None, 19, None, 12, None, 18],
- [22, None, 15, None, 20, None]]
- eval_matrix = [
- [0, None, 0, None, 1, None],
- [None, 1, None, 1, None, 0],
- [7, None, 6, None, 4, None],
- [None, 13, None, 9, None, 11],
- [19, None, 12, None, 18, None],
- [None, 22, None, 15, None, 20]]
- eval_matrix_enemy = list(reversed(eval_matrix2))
- def evaluate(state, player):
- res = 0
- for i, row in enumerate(state):
- for j, x in enumerate(row):
- res += x * 100
- if x == 0:
- continue
- t = 1 if x > 0 else -1
- p1 = i - t, j + 1
- p2 = i - t, j - 1
- if not is_free(state, p1) and not is_free(state, p2):
- res += 20 * t
- if x > 0:
- res += eval_matrix[i][j] * x * 3
- if x < 0:
- res += eval_matrix_enemy[i][j] * x * 3
- res += len(get_moves(state, False)) * 10 - len(get_moves(state, True)) * 10
- # если нас могут срубить, то это плохо
- #capture_penalty = 0
- #for m in get_moves(state, not is_enemy, only_capture=True):
- # capture_penalty = max(capture_penalty, (len(m) - 1) * 100)
- #res -= capture_penalty
- res *= player
- return res
- def apply_move(state, move):
- state = copy.deepcopy(state)
- me = state[move[0][0]][move[0][1]]
- # kings
- rows = [x[0] for x in move]
- if me == 1 and 5 in rows:
- me = 2
- if me == -1 and 0 in rows:
- me = -2
- for (i1, j1), (i2, j2) in zip(move, move[1:]):
- di = 1 if i2 > i1 else -1
- dj = 1 if j2 > j1 else -1
- i = i1
- j = j1
- while i != i2:
- if state[i][j] != 0:
- state[i][j] = 0
- i += di
- j += dj
- if state[i][j] != 0:
- state[i][j] = 0
- state[move[-1][0]][move[-1][1]] = me
- return state
- def move_str(move):
- if move == None:
- return None
- return '-'.join('%s%d' % (chr(ord('a') + j), i + 1) for i, j in move)
- def get_move(state, player):
- best = None
- best_val = -1e30
- for move in get_moves(state, player):
- state2 = apply_move(state, move)
- best_enemy = None
- best_enemy_val = 1e30
- for emove in get_moves(state2, -player):
- state3 = apply_move(state2, emove)
- v = evaluate(state3, player)
- if v < best_enemy_val:
- best_enemy_val = v
- best_enemy = emove
- #value = evaluate(state2)
- value = best_enemy_val
- print("%s: %d" % (move_str(move), value))
- #print_state(state2)
- if value > best_val:
- best_val = value
- best = move
- print("Best: %s: %d" % (move_str(best), best_val))
- return best
- init_state = [
- [1, 0, 1, 0, 1, 0],
- [0, 1, 0, 1, 0, 1],
- [0, 0, 0, 0, 0, 0],
- [0, 0, 0, 0, 0, 0],
- [-1, 0, -1, 0, -1, 0],
- [0, -1, 0, -1, 0, -1]]
- def print_state(state):
- for i, row in enumerate(reversed(state)):
- s = str(6-i)
- for j, x in enumerate(row):
- s += Back.BLUE if (i + j) % 2 == 1 else Back.GREEN
- if x == 0:
- s += ' '
- else:
- s += Fore.WHITE if x > 0 else Fore.RED
- s += Style.BRIGHT
- if abs(x) == 1:
- s += 'o'
- elif abs(x) == 2:
- s += '@'
- else:
- s += '?'
- s += Fore.RESET + Style.RESET_ALL
- s += Back.RESET
- print(s)
- print(' abcdef')
- def play_with_user(user_player):
- state = init_state
- first_move = True
- while True:
- if user_player == -1 or not first_move:
- move = get_move(state, -user_player)
- if move == None:
- print("Game Over. You won! :c")
- return
- state = apply_move(state, move)
- print_state(state)
- first_move = False
- while True:
- e_moves = get_moves(state, user_player)
- if not e_moves:
- print("Game Over. You lost! c:")
- return
- print('Available moves:')
- for i, m in enumerate(e_moves):
- print('%d %s' % (i+1, move_str(m)))
- s = input()
- try:
- idx = int(s)
- m = e_moves[idx-1]
- break
- except:
- pass
- s = s.split('-')
- m = []
- try:
- for x, y in s:
- m.append((ord(y) - ord('1'), ord(x) - ord('a')))
- except:
- print("invalid move")
- print("expected: %s" % ', '.join(move_str(x) for x in e_moves))
- continue
- if not m in e_moves:
- print("invalid move")
- print("expected: %s" % ', '.join(move_str(x) for x in e_moves))
- else:
- break
- state = apply_move(state, m)
- print_state(state)
- def main():
- colorama.init()
- print("1 = white, -1 = black")
- player = int(input())
- assert(player in [1, -1])
- play_with_user(player)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement