Posts: 9
Threads: 3
Joined: Oct 2016
Oct-31-2016, 07:24 PM
(This post was last modified: Oct-31-2016, 07:53 PM by snippsat.)
I am writing a tic-tac-toe style game code, where you use 3 variables to make 3 in a row instead of just X's and O's. I originally wrote a tic-tac-toe game, and tried to modify it from there.
The only thing I am stuck on is replacing variables like the game allows. For example: When I input 1, it outputs "G". When I try to input 1 again to input the replacement variable, "Y" my code currently does not allow that.
Link image
I am pretty sure that my problem lies with the make_move function, but I do not know how to edit it to allow the overwrite of inputs. Any help is appreciated, Thank you!
def play_game():
def print_board():
print(board[1], board[2], board[3])
print(board[4], board[5], board[6])
print(board[7], board[8], board[9])
board = [None] + list(range(1, 10))
combinations = [
(1, 5, 9),
(3, 5, 7),
(1, 4, 7),
(2, 5, 8),
(3, 6, 9),
(1, 2, 3),
(4, 5, 6),
(7, 8, 9),
]
def make_move():
while True:
try:
a = int(input())
if a in board:
return a
else:
print("\nCannot Overwrite")
except ValueError:
print("\nIncorrect Input")
def check_winner():
for a, b, c in combinations:
if board[a] == board[b] == board[c]:
print("\nGame Over\n")
return True
#update_board
for player in "GYR" * 9:
print_board()
if check_winner():
break
board[make_move()] = player
while True:
play_game()
Posts: 4,220
Threads: 97
Joined: Sep 2016
I'm not sure what your question is or what you are shooting for. The first time you type one, player is 'G'. The make_move function returns 1, since is on the board. So board[make_move()] = player replaces the 1 with a 'G'. The second time you type 1, there is no 1 on the board, since you just replaced it with a 'G'. So the make_move prints cannot overwrite. Then I guess you get an error? That would have been helpful to point out.
You see, functions always return something. If you don't specify something else for it to return, it will return None. So board[make_move()] = player becomes board[None] = player, and that's an error, because only integers can be used as list indices. What you want to do is check the result of make_move() before trying to assign with it. If it's None (some error occurred), you want to get another move for the same player. Typically this is done with a while loop:
while True:
move = make_move()
if move is not None:
board[move] = player
break BTW, your structure is really screwy. Yeah, you can define your functions inside another function, but generally you define all the functions at the module level and have them call each other. I would do that, and pass the board as a parameter to print_board and check_winner.
Posts: 9
Threads: 3
Joined: Oct 2016
Nov-01-2016, 02:33 AM
(This post was last modified: Nov-01-2016, 02:33 AM by palmtrees.)
I'm trying to ask how I can rework the program so that whenever I type in an int value, it will be replaced with the next variable when it turns into a string, whether it is G/Y/R.
Posts: 12,032
Threads: 486
Joined: Sep 2016
Nov-01-2016, 05:47 PM
(This post was last modified: Nov-01-2016, 05:47 PM by Larz60+.)
This still may have bugs and other issues ... I cranked it out pretty quickly and didn't thoroughly test.
the main purpose is to show different ways of writing the code;
from itertools import chain
class TicTacToe:
def __init__(self):
self.board = self.new_board()
self.winners = [
[0, 1, 2], [3, 4, 5], [6, 7, 8], # rows
[0, 3, 6], [1, 4, 7], [2, 5, 8], # columns
[0, 4, 8], [2, 4, 6] # diags
]
def new_board(self):
return [['_'] * 3 for i in range(3)]
def display_board(self):
print('\n 1 2 3')
for n, row in enumerate(self.board):
print('{} | {} | {} | {} |'.format(n + 1, row[0], row[1], row[2]))
print()
def place_item(self, row, column, value):
if self.board[row][column] == '_':
self.board[row][column] = value
else:
print('Already occupied')
def clear_board(self):
for x in range(3):
for y in range(3):
self.place_item(x, y, '_')
def check_winner(self):
flat_board = list(chain.from_iterable(self.board))
for winner in self.winners:
if flat_board[winner[0]] == flat_board[winner[1]] == flat_board[winner[2]]:
if flat_board[winner[0]] != '_':
return flat_board[winner[0]]
return None
def rungame() -> object:
game = TicTacToe()
game.display_board()
turn = 'X'
while True:
# game.make_move()
row = column = value = None
while True:
try:
ttext = "{}'s Turn -- 'Q' to quit: ".format(turn)
row, column = input(ttext).split()
if row == 'Q':
break
row = int(row) - 1
column = int(column) - 1
if (row < 0 or row > 2) or (column < 0 or column > 2):
raise ValueError from ValueError
value = turn
break
except:
print('Value error, enter row, column or Q to Quit) please')
if row == 'Q':
break
game.place_item(row, column, value)
game.display_board()
winner = game.check_winner()
if winner:
print('The winner is {}'.format(winner))
break
if turn == 'X':
turn = 'Y'
else:
turn = 'X'
if __name__ == '__main__':
rungame()
Posts: 9
Threads: 3
Joined: Oct 2016
Is there a way for me to edit my existing code to be able to overwrite the string variable once it is inputted? Because the int is still there in the list after it is transitioned to a string variable, I just need to be able to continuously change that string variable in a position with each input of an int
Posts: 4,220
Threads: 97
Joined: Sep 2016
Nov-01-2016, 08:39 PM
(This post was last modified: Nov-02-2016, 01:07 AM by ichabod801.)
(Nov-01-2016, 06:33 PM)palmtrees Wrote: Is there a way for me to edit my existing code to be able to overwrite the string variable once it is inputted? Because the int is still there in the list after it is transitioned to a string variable, I just need to be able to continuously change that string variable in a position with each input of an int
Then you probably want to change this check:
if a in board: That is what is preventing the second character being written in the same space. If you want to rewrite spaces, you should just check that a is in the range of allow indices for the board:
if 0 < a < len(board):
Posts: 9
Threads: 3
Joined: Oct 2016
That worked perfectly, thank you so much! Sorry for being difficult, I wasn't sure how to exactly word my question.
Posts: 3,458
Threads: 101
Joined: Sep 2016
That's honestly the #1 problem beginners have. It isn't enough that you're learning something entirely new, but it's so different from everything you know that you don't even know how to phrase your questions to ask for help. I promise it gets better the more you learn :)
|