from random import choice
import numpy as np
combo_indices = [
[0,1,2],
[3,4,5],
[6,7,8],
[0,3,6],
[1,4,7],
[2,5,8],
[0,4,8],
[2,4,6]
]
EMPTY_SIGN = '.'
AI_SIGN = 'X'
OPPONENT_SIGN = 'O'
def all_moves_from_board(board, sign):
move_list = []
for i,v in enumerate(board):
if v == EMPTY_SIGN:
move_list.append(board[:1] + sign + board[i+1:])
return move_list
def game_won_by(board):
for index in combo_indices:
if board[index[0]] == board[index[1]] == board[index[2]] != EMPTY_SIGN:
return board[index[0]]
return EMPTY_SIGN
def filter_wins(move_list, ai_wins, opponent_wins):
for board in move_list:
won_by = game_won_by(board)
if won_by == AI_SIGN:
ai_wins.append(board)
move_list.remove(board)
elif won_by == OPPONENT_SIGN:
opponent_wins.append(board)
move_list.remove(board)
def init_utility_matrix(board):
return [0 if cell == EMPTY_SIGN else -1 for cell in board]
def generate_add_score(utilities, i , j, k):
def add_score(points):
if utilities[i] >= 0:
utilities[i] += points
if utilities[j] >= 0:
utilities[j] += points
if utilities[k] >= 0:
utilities[k] += points
return add_score
def utility_matrix(board):
utilities = init_utility_matrix(board)
for [i,j,k] in combo_indices:
add_score = generate_add_score(utilities, i, j, k)
triple = [ board[i], board[j], board[k]]
if triple.count(EMPTY_SIGN) == 1:
if triple.count(AI_SIGN) == 2:
add_score(1000)
elif triple.count(OPPONENT_SIGN) == 2:
add_score(100)
elif triple.count(EMPTY_SIGN) == 2 and triple.count(AI_SIGN) == 1:
add_score(10)
elif triple.count(EMPTY_SIGN) == 3:
add_score(1)
return utilities
def best_moves_from_board(board, sign):
move_list =[]
utilities = utility_matrix(board)
max_utility = max(utilities)
for i,v in enumerate(board):
if utilities[i] == max_utility:
move_list.append(board[:i] + sign + board[i+1:])
return move_list
def all_moves_from_board_list(board_list, sign):
move_list = []
get_moves = best_moves_from_board if sign == AI_SIGN else all_moves_from_board
for board in board_list:
move_list.extend(get_moves(board, sign))
return move_list
def count_possibilities():
board = EMPTY_SIGN*9
move_list = [board]
ai_wins = []
opponent_wins = []
for i in range(9):
print(' step ' + str(i) + '. Moves: ' + str(len(move_list)))
sign = AI_SIGN if i%2==0 else OPPONENT_SIGN
move_list = all_moves_from_board_list(move_list, sign)
filter_wins(move_list, ai_wins, opponent_wins)
print('First player wins: ' + str(len(ai_wins)))
print('Second player wins: ' + str(len(opponent_wins)))
print('Draw: ' + str(len(move_list)))
print('Total: ' + str(len(ai_wins) + len(opponent_wins) + len(move_list) ))
count_possibilities()
This is my code above...
i am getting this error:-
IndexError Traceback (most recent call last)
Input In \[3\], in \<cell line: 107\>()
103 print('Draw: ' + str(len(move_list)))
104 print('Total: ' + str(len(ai_wins) + len(opponent_wins) + len(move_list) ))
\--\> 107 count_possibilities()
Input In \[3\], in count_possibilities()
98 sign = AI_SIGN if i%2==0 else OPPONENT_SIGN
99 move_list = all_moves_from_board_list(move_list, sign)
\--\> 100 filter_wins(move_list, ai_wins, opponent_wins)
101 print('First player wins: ' + str(len(ai_wins)))
102 print('Second player wins: ' + str(len(opponent_wins)))
Input In \[3\], in filter_wins(move_list, ai_wins, opponent_wins)
34 def filter_wins(move_list, ai_wins, opponent_wins):
35 for board in move_list:
\---\> 36 won_by = game_won_by(board)
37 if won_by == AI_SIGN:
38 ai_wins.append(board)
Input In \[3\], in game_won_by(board)
27 def game_won_by(board):
28 for index in combo_indices:
\---\> 29 if board\[index\[0\]\] == board\[index\[1\]\] == board\[index\[2\]\] != EMPTY_SIGN:
30 return board\[index\[0\]\]
31 return EMPTY_SIGN
IndexError: string index out of range
while calling the game_won_by function and then checking the if state for indexes 0,1,2 for board iteration it is showing string index out of range...
Please help anyone...
Error resolution :- String index out of range
In function all_moves_from_board
I think it should be
move_list = []
for i, v in enumerate(board):
if v == EMPTY_SIGN:
move_list.append(board[:i] + sign + board[i + 1:])
return move_list
You accidentally wrote the first slicing of the board index to 1. I have not checked whether the code is working as it's intended to or not but now it runs and generates an output:
step 0. Moves: 1
step 1. Moves: 1
step 2. Moves: 8
step 3. Moves: 24
step 4. Moves: 144
step 5. Moves: 83
step 6. Moves: 214
step 7. Moves: 148
step 8. Moves: 172
First player wins: 504
Second player wins: 12
Draw: 91
Total: 607