I am a beginner in Python. I started to write some code for a game called 'Tic tac toe'.
For that I created some functions below:
import random
def choose_first():
random.randint(1, 2)
if random.randint(1,2) == 1:
print('Player 1 is first to play')
player1_input()
elif random.randint(1,2) == 2:
print('Player 2 is first to play')
player2_input()
def player1_input():
player1=''
marker=''
while marker !='X' and marker !='O':
marker=input('Player 1, choose X or O: ')
return marker
player1==marker
if player1=='X':
player2='O'
else:
player2='X'
return (player1,player2,marker)
def player_choice(board):
position = int(input('Which position you want to choose? '))
if space_check is True:
return position
def place_marker(board, marker, position):
board[position] = marker
Here is piece of code that using those functions:
def game_on():
board = ['#','','','','','','','','','']
choose_first()
while not full_board_check(board):
player_choice(board)
place_marker(board, marker, position)
display_board(board)
while full_board_check(board):
if win_check(board, mark):
print('Player using', marker, 'won')
else:
print("It's a tie!")
When I choosing position it returns this error:
<ipython-input-117-d37edecdd743> in game_on()
5 while not full_board_check(board):
6 player_choice(board)
----> 7 place_marker(board, marker, position)
8 display_board(board)
9 while full_board_check(board):
NameError: name 'marker' is not defined
It seems that the 'marker' variable doesn't return from player_input() but I need to use him at another function (in this situation for placing marker). How to do that? Please help if you can.
I think what you should do is to put global marker before getting the input:
global marker
marker=input('Player 1, choose X or O: ')
Related
I'm new to python and writing my first project. I'm trying to implement a check that if a space is already occupied, not to move there. I can't seem to figure out why my move_player method overwrites the index value of the board even though I am explicitly checking it (If it is O's turn and X has already been placed in the index O is trying to move to, it just overwrites it). I have tried hard coding the check for 'X' and 'O' instead of player.player as well but can't seem to figure it out. Does it have to do something with how Python works or am I implementing it wrong?
class Player:
def __init__(self, player):
self.player = player
class Board:
def __init__(self):
self.board = [[' ' for i in range(3)] for j in range(3)]
def display_board(self):
print('---------')
for row in self.board:
print('| ', end='')
for col in row:
print(f'{col} ', end='')
print('|')
print('---------')
def move_player(self, player):
try:
p1 = Player('X')
p2 = Player('O')
coordinates = [int(i) for i in input("Enter coordinates for move: ").split()]
xCoordinate = coordinates[0]
yCoordinate = coordinates[1]
if ((self.board[xCoordinate][yCoordinate] == p1.player) or
(self.board[xCoordinate][yCoordinate] == p2.player)):
print("That space is occupied, please choose another one.")
self.move_player(player)
else:
self.board[xCoordinate - 1][yCoordinate - 1] = player.player
except (ValueError, IndexError):
print("Please only enter numbers between 1 and 3.")
self.move_player(player)
def has_won(self, player):
if self.check_diagonal(player):
return True
elif self.check_across(player):
return True
elif self.check_down(player):
return True
return False
if __name__ == '__main__':
board = Board()
player1 = Player('X')
player2 = Player('O')
player = player1
while True:
board.display_board()
board.move_player(player)
if board.has_won(player):
board.display_board()
print(f'{player.player} wins!!!')
break
if player == player1:
player = player2
else:
player = player1
The code is very convoluted but from what I can see:
if ((self.board[xCoordinate][yCoordinate] == p1.player) or
(self.board[xCoordinate][yCoordinate] == p2.player)):
...
self.board[xCoordinate - 1][yCoordinate - 1] = player.player
You are checking [x,y] but assigning to [x-1,y-1].
I'm writing a sum up game where two players will take turns picking a random number in the range (1,9), no repeated number allowed. If the first player picks [7, 2, 3, 5], he will win because 7+3+5 = 15
So my question is why doesn't the program stop when first_player has a sum of inputs that == 15
Below is the readme file
The game doesn't stop when first player's inputs equal 15 because you ask for second player's input regardless of whether the first player won. You can see this in your testing code, where you have two while statements for each player's input. If you complete that round with second player's input, your program works and stops there. To stop when a player wins on input, just add the conditional check to break out of main loop before asking for next player's input.
Your script is too verbose. If you made it more dynamic, with reusable logic, it becomes much easier to work with. I rewrote your game as an example.
notes:
All the game states are reused in fstrings, as dict keys, and even to represent the player
The game loop (update()) represents a single turn, and the player that turn corresponds to is toggled at the end of the loop
make_move also represents one turn
the entire game is contained in the class
reset() is used to clear the window, reset all the game properties, and start the loop, but the very first time it is called it acts as an initializer for all of the game properties.
There is never going to be an instance where both players have 15 points
import os
UNFINISHED = "unfinished"
DRAW = "draw"
FIRST_WON = "First"
SECOND_WON = "Second"
CLEAR = lambda: os.system('cls') #windows only
class AddThreeGame:
#property
def current_state(self):
return self.__state
#property
def player(self):
return self.__rotation[self.__player]
def __init__(self):
self.__rotation = [FIRST_WON, SECOND_WON]
self.__states = {
UNFINISHED:'We have unfinished business, come back for more\n',
DRAW:'Draw game\n',
FIRST_WON:'First player won this game!!!\n',
SECOND_WON:'Second player won this game!!!\n',
}
self.reset()
def make_move(self, player, number):
if number not in range(1, 10) or number in self.__input:
return False
self.__input.append(number)
self.__players[self.player].append(number)
if len(self.__players[self.player]) >= 3:
L = self.__players[self.player]
for i in range(0, len(L)-2):
for j in range(i+1, len(L)-1):
for k in range(j+1, len(L)):
if (L[i] + L[j] + L[k]) == 15:
self.__state = player
return True
if len(self.__input) == 9:
self.__state = DRAW
return True
def update(self):
while True:
num = int(input(f'{self.player} player please enter a number from 1 to 9: '))
while True:
if self.make_move(self.player, num):
break
else:
num = int(input("Wrong input, please try a different number: "))
if self.current_state == UNFINISHED:
if self.__player == 1: #technically, this is player 2
print(self.__states[self.current_state])
#next player
self.__player = (self.__player + 1) % 2
else:
print(self.__states[self.current_state])
break
if input('Play Again? (y or n): ') == 'y':
self.reset()
def reset(self):
CLEAR()
self.__player = 0
self.__input = []
self.__state = UNFINISHED
self.__players = {
FIRST_WON:[],
SECOND_WON:[],
}
self.update()
if __name__ == '__main__':
AddThreeGame()
import numpy as np
player1 = True
def create_board():
board = np.zeros((3,3), dtype=int)
return board
def place(board , player1 , position ):
if player1 == True:
player1 = False
if board[position] == 0:
board = position
elif board[position] != 0:
print("False , place taken 1")
else:
if player1 == False:
if board[position] == 0:
board = position
elif board[position] != [0, 0]:
print("False , place taken 2 ")
return board
Function call:
place(board=create_board() , player1=1 , position=(0,0))
Here is my code, in this code there is a lot going on however there is one part i could not get it right . In the bold section , i am trying to replace
([0,0,0],
[0,0,0],
[0,0,0])
to
([1,0,0],
[0,0,0],
[0,0,0])
May i know , how can I do this please ... Thank you !
you're mistakenly changing the board variable to position inside the if statements
if board[position] == 0:
board = position
you should change the value inside board at index position
board[position] = 1 # for player 1
board[position] = 2 # for player 2
i've also cleaned the code a little bit
def place(board , player1 , position ):
x = 1 if player1 else 2
if board[position] != 0:
print(f'False , place taken {x}')
else:
board[position] = x
return board
You are assigning your board to your position information with board = position and I think you mean board[position] == 1
def place(board , player, position ):
if board[position] == 0: #if the position is unclaimed
board[position] = player #claim it for the player
else:
print(f"place was already taken by player {board[position]}")
return board
#call using the player number
place(board=create_board() , player=1 , position=(0,0))
This function would give you what you are looking for.
When you try to update your board in board = position you are actually updating the whole board with your pair of coordinates.
What you really want is to pinpoint the exact position in your two-dimensional array that you have to update to store an occupied cell. You could archieve that changing that line with
board[position] = 1 # occupied cell
However, as Hammad said in another answer, it would be convienient to change your
0 for unoccupied
1 for occupied
and having to rely on knowing whose turn is ongoing at the moment, to
0 for unoccupied
1 for occupied by player one
2 for occupied by player two
so you always know who occupied that cell.
I have an excercise to do and I'm stuck. It's the board game Alak, not much known, that I have to code in python. I can link the execrcise with the rules so you can help me better. The code has the main part and the library with all the procedures and function.
from Library_alak import *
n = 0
while n < 1:
n = int(input('Saisir nombre de case strictement positif : '))
loop = True
player = 1
player2 = 2
removed = [-1]
board = newboard(n)
display(board, n)
while loop:
i = select(board, n, player, removed)
print(i)
board = put(board, player, i)
display(board, n)
capture(board, n, player, player2)
loop = True if again(board, n, player, removed) is True else False
if player == 1 and loop:
player, player2 = 2, 1
elif player == 2 and loop:
player, player2 = 1, 2
win(board, n)
print(win(board, n))
And here is the library:
def newboard(n):
board = ([0] * n)
return board
def display(board, n):
for i in range(n):
if board[i] == 1:
print('X', end=' ')
elif board[i] == 2:
print('O', end=' ')
else:
print(' . ', end=' ')
def capture(board, n, player, player2):
for place in range(n):
if place == player:
place_beginning = place
while board[place] != player:
place_end = place
if board[place + x] == player:
return board
else:
return board
def again(board, n, player, removed):
for p in board(0):
if p == 0:
if p not in removed:
return True
else:
return False
def possible(n, removed, player, i, board):
for p in range(n + 1):
if p == 1:
if board[p-1] == 0:
if p not in removed:
return True
else:
return False
def win(board, n):
piecesp1 = 0
piecesp2 = 0
for i in board(0):
if i == 1:
piecesp1 += 1
else:
piecesp2 += 1
if piecesp1 > piecesp2:
print('Victory : Player 1')
elif piecesp2 > piecesp1:
print('Victory : Player 2')
else:
return 'Equality'
def select(board, n, player, removed):
loop = True
while loop:
print('player', player)
i = int(input('Enter number of boxes : '))
loop = False if possible(n, removed, player, i, board)is True else True
return i
def put(board, player, i):
i -= 1
if board[i] == 0:
if player == 1:
board[i] = 1
return board
else:
board[i] = 2
return board
else:
put(board, player, i)
So my problems here are that I have few errors, the first one is that when I enter the number '1' when asked to enter a number of boxes ( which is the place to play on ) nothing happens. Then when entering any other number, either the error is : if board[place + x] == player:
NameError: name 'x' is not defined
or there seems to be a problem with the : if board[place + x] == player:
NameError: name 'x' is not defined
I would appreciate a lot if anyone could help me. I'm conscious that it might not be as detailed as it should be and that you maybe don't get it all but you can contact me for more.
Rules of the Alak game:
Black and white take turns placing stones on the line. Unlike Go, this placement is compulsory if a move is available; if no move is possible, the game is over.
No stone may be placed in a location occupied by another stone, or in a location where a stone of your own colour has just been removed. The latter condition keeps the game from entering a neverending loop of stone placement and capture, known in Go as ko.
If placing a stone causes one or two groups of enemy stones to no longer have any adjacent empty spaces--liberties, as in Go--then those stones are removed. As the above rule states, the opponent may not play in those locations on their following turn.
If placing a stone causes one or two groups of your own colour to no longer have any liberties, the stones are not suicided, but instead are safe and not removed from play.
You shouldn't use "player2" as a variable, there's an easier way, just use "player" which take the value 1 or 2 according to the player. You know, something like that : player = 1 if x%2==0 else 2
and x is just a increasing int from 0 until the end of the game.
def take_turn(Nplayers, hands, player, pile, turn):
while finished(hands) is not True:
pile.append(hands[player][0]) # this line
hands[player].pop(0)
while pile[-1] <= 10:
print(turn, ':', '\nPile:', pile, '\nHands\n', '\n'.join(map(str, hands)), '\n')
check_players(Nplayers, hands, player, pile, turn)
turn += 1
player = (player + 1) % Nplayers
if len(hands[player]) == 0:
hands.pop(player)
Nplayers -= 1
player = player % Nplayers
pile.append(hands[player][0])
hands[player].pop(0)
if table[-1] > 10:
break
penalty_card(Nplayers, hands, player, pile, turn)
return turn
The line marked by the (# this line) returns the error as stated in the title, in my programme I have set player to initially equal 0, so there should be no problems right?
Edit: hands is a list of lists, player is an integer
It would be a lot easier to help if a working code sample were provided. It looks like there's a number of functions with side effects. Perhaps you could include some minimal mocks and a sample call like below to make a contained, runnable demonstration of the problem?
def finished(hands):
if len(hands) == 0:
return True
return False
def check_players(*args, **kwargs):
pass
def penalty_card(*args, **kwargs):
pass
table = [9]
def take_turn(Nplayers, hands, player, pile, turn):
while finished(hands) is not True:
pile.append(hands[player][0]) # this line
hands[player].pop(0)
while pile[-1] <= 10:
print(turn, ':', '\nPile:', pile, '\nHands\n', '\n'.join(map(str, hands)), '\n')
check_players(Nplayers, hands, player, pile, turn)
turn += 1
player = (player + 1) % Nplayers
if len(hands[player]) == 0:
hands.pop(player)
Nplayers -= 1
player = player % Nplayers
pile.append(hands[player][0])
hands[player].pop(0)
if table[-1] > 10:
break
penalty_card(Nplayers, hands, player, pile, turn)
return turn
take_turn(Nplayers=1, hands=[[1,1,1], [1,1], [1]], player=0, pile=[5, 5], turn=3)