Reputation: 59
This is a 8 by 8 array the problem is when I set the variable player_2_move to the row and column which is input we get from the user the value of that variable stays at 0 when its meant to go to the two inputs we get. And from there I don't know how to change the value which Is Player 2 move this only happens when a function which checks for a winning move is checked. The two inputs work when I call the drop piece function which is most confusing. And also I'm still drafting with arrays which is why the numbers are 1 and 2. The game I'm making is called Othello.
import pygame, sys
import math
pygame.init()
ROW_COUNT = 8
COLUMN_COUNT = 8
PLAYER_COUNT = 2
RED = (255, 0, 0)
BEIGE = (255, 200, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
SQUARESIZE = 100
width = COLUMN_COUNT * SQUARESIZE
height = ROW_COUNT * SQUARESIZE
size = (width, height)
screen = pygame.display.set_mode(size)
screen.fill(RED)
# Vertical
one_x_1 = 100
one_y_1 = 0
one_end_x = 100
one_end_y = 800
# Horizontal
two_x_1 = 0
two_y_1 = 100
two_end_x = 800
two_end_y = 100
RADIUS = int(SQUARESIZE/2 - 5)
def draw_board(board):
global one_x_1, one_y_1, one_end_x, one_end_y, two_x_1, two_y_1, two_end_x, two_end_y
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
pygame.draw.line(screen, BLACK, (one_x_1, one_y_1), (one_end_x, one_end_y), 3)
one_x_1 += 100
one_end_x += 100
pygame.draw.line(screen, BLACK, (two_x_1, two_y_1), (two_end_x, two_end_y), 3)
two_y_1 += 100
two_end_y += 100
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
if board[r][c] == 1:
pygame.draw.circle(screen, WHITE, (int(c*SQUARESIZE+SQUARESIZE/2), height - int(r*SQUARESIZE + SQUARESIZE/2)), RADIUS)
elif board[r][c] == 2:
pygame.draw.circle(screen, BLACK, (int(c*SQUARESIZE+SQUARESIZE/2), height - int(r*SQUARESIZE + SQUARESIZE/2)), RADIUS)
pygame.display.update()
class Player(object):
def __init__(self, number):
self.remaining_pieces = 32
self.number = number
board = np.zeros((ROW_COUNT, COLUMN_COUNT), dtype=np.uint8)
board[3][3] = 1
board[4][4] = 1
board[3][4] = 2
board[4][3] = 2
print(board)
draw_board(board)
pygame.display.update()
players = [Player(i) for i in range(1, PLAYER_COUNT + 1)]
print(len(players))
game_over = False
while not game_over:
# Event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
for p in players:
if event.type == pygame.MOUSEBUTTONDOWN:
posx = event.pos[0]
posy = event.pos[1]
column = int(math.floor(posx/SQUARESIZE))
row = int(math.floor(posy/SQUARESIZE))
if board[row][column] == 0:
board[row][column] = p.number
p.remaining_pieces = p.remaining_pieces - 1
# The eight directions in which we will go
directions = [(-1, -1), (-1, 0), (-1, 1), (1, 1), (1, 0), (1, -1), (0, 1), (0, -1)]
for d in directions:
x = row
y = column
while True:
x = x + d[0] # Assign x to the first value in the tuple
y = y + d[1] # Assign y to the second value in the tuple
# check if we are still on the board
if (x in range(8)) and (y in range(8)):
print(f'checking y = {x + 1}, x = {y + 1}')
# if the file is empty there are no pieces to capture
if board[x][y] == 0:
break
"""
If we find a number around our move we run the same procedure for it and change it
if we have to
"""
if p.number == board[x][y]: # Here p.number is the players move we find it on the board
print(f'found {p.number}: y = {x + 1}, x = {y + 1}')
i = row
j = column
while i != x or j != y:
i = i + d[0]
j = j + d[1]
print(f'changed : y = {i + 1}, x = {j + 1} to {p.number}')
board[i][j] = p.number
else:
# We are outside the board
break
draw_board(board)
print(board)```
Upvotes: 1
Views: 1303
Reputation: 189
I will go step by step through your program and improve it. First of all creating arrays like this:
player1 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
player2 = [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
Is always a bad practice. Since you already use numpy in your project it's easy to create them like this:
player1 = np.ones(32, dtype=np.uint8)
player2 = np.full(32, 2, dtype=np.uint8)
However you don't really need those arrays anyway. You can just have an integer which keeps track of the remaining pieces. reamining_pieces = 32
To make the whole think easier I created a Player class which contains a Player number and the remaining Pieces.
class Player(object):
def __init__(self, number):
self.remaining_pieces = 32
self.number = number
Now after this you have a lot of functions which aren't really necessary. They are so simple that there is no advantage of writing a function for them. So for example instead of writing
def create_board():
board = np.zeros((ROW_COUNT, COLUMN_COUNT))
return board
board = create_board()
It's a lot simpler and easier to read if you just write
board = np.zeros((ROW_COUNT, COLUMN_COUNT))
Same goes for def drop_piece(board, row, col, piece)
and def is_valid_location(board, row, col)
which both just add unnecessary complexity to it.
First, we start with a tuple of all directions:
directions = [(-1, -1), (-1, 0), (-1, 1), (1, 1), (1, 0), (1, -1), (0, 1), (0, -1)]
And we now want to go in all directions and every time we start at row, column
which is where the newly placed piece is located.
for d in directions:
x = row
y = column
And since we don't know how far we have to go we use a while loop and take the first step in the direction. Because We don't want to go outside of the board we immediately check if we are still on the board. If we are, we can continue.
while True:
x = x + d[0]
y = y + d[1]
# check if we are still on the board
if (x in range(8)) and (y in range(8)):
For the following steps let's use this as an example:
[[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 1 2 0 0 0]
[0 0 * 2 1 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]]
The star is where has just been placed a one. If we go one step to the left, we will encounter a 0 and know that we don't have to go any further. That's what
if board[x][y] == 0:
break
Does.
If we now go to the right. We will first encounter a two and it just get's ignored and we go one step further to the right.
Here we finally find a one. So we know that between row, column
and x, y
every number can be converted to a one. To do that we start at row, column
and move once again until we reach x, y
. On the way we convert every number to a one:
if p.number == board[x][y]:
print(f'found {p.number}: x = {x + 1}, y = {y + 1}')
i = row
j = column
while i != x or j != y:
i = i + d[0]
j = j + d[1]
print(f'changed : x = {i + 1}, y = {j + 1} to {p.number}')
board[i][j] = p.number
import pygame, sys
import math
import numpy as np
pygame.init()
ROW_COUNT = 8
COLUMN_COUNT = 8
PLAYER_COUNT = 2
RED = (255, 0, 0)
BEIGE = (255, 200, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
SQUARESIZE = 100
width = COLUMN_COUNT * SQUARESIZE
height = ROW_COUNT * SQUARESIZE
size = (width, height)
screen = pygame.display.set_mode(size)
screen.fill(RED)
# Vertical
one_x_1 = 100
one_y_1 = 0
one_end_x = 100
one_end_y = 800
# Horizontal
two_x_1 = 0
two_y_1 = 100
two_end_x = 800
two_end_y = 100
RADIUS = int(SQUARESIZE / 2 - 5)
def draw_board(board):
global one_x_1, one_y_1, one_end_x, one_end_y, two_x_1, two_y_1, two_end_x, two_end_y
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
pygame.draw.line(screen, BLACK, (one_x_1, one_y_1), (one_end_x, one_end_y), 3)
one_x_1 += 100
one_end_x += 100
pygame.draw.line(screen, BLACK, (two_x_1, two_y_1), (two_end_x, two_end_y), 3)
two_y_1 += 100
two_end_y += 100
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
if board[r][c] == 1:
pygame.draw.circle(screen, WHITE, (
int(c * SQUARESIZE + SQUARESIZE / 2), height - int(r * SQUARESIZE + SQUARESIZE / 2)), RADIUS)
elif board[r][c] == 2:
pygame.draw.circle(screen, BLACK, (
int(c * SQUARESIZE + SQUARESIZE / 2), height - int(r * SQUARESIZE + SQUARESIZE / 2)), RADIUS)
pygame.display.update()
class Player(object):
def __init__(self, number):
self.remaining_pieces = 32
self.number = number
board = np.zeros((ROW_COUNT, COLUMN_COUNT), dtype=np.uint8)
board[3][3] = 1
board[4][4] = 1
board[3][4] = 2
board[4][3] = 2
print(board)
draw_board(board)
pygame.display.update()
players = [Player(i) for i in range(1, PLAYER_COUNT + 1)]
print(len(players))
def next_player():
while True:
for player in players:
yield player
player_generator = next_player()
game_over = False
while not game_over:
# Event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
posx = event.pos[0]
posy = event.pos[1]
column = int(math.floor(posx / SQUARESIZE))
row = int(math.floor(posy / SQUARESIZE))
p = player_generator.__next__()
if board[row][column] == 0:
board[row][column] = p.number
p.remaining_pieces = p.remaining_pieces - 1
# The eight directions in which we will go
directions = [(-1, -1), (-1, 0), (-1, 1), (1, 1), (1, 0), (1, -1), (0, 1), (0, -1)]
for d in directions:
x = row
y = column
while True:
x = x + d[0] # Assign x to the first value in the tuple
y = y + d[1] # Assign y to the second value in the tuple
# check if we are still on the board
if (x in range(8)) and (y in range(8)):
print(f'checking y = {x + 1}, x = {y + 1}')
# if the file is empty there are no pieces to capture
if board[x][y] == 0:
break
"""
If we find a number around our move we run the same procedure for it and change it
if we have to
"""
if p.number == board[x][y]: # Here p.number is the players move we find it on the board
print(f'found {p.number}: y = {x + 1}, x = {y + 1}')
i = row
j = column
while i != x or j != y:
i = i + d[0]
j = j + d[1]
print(f'changed : y = {i + 1}, x = {j + 1} to {p.number}')
board[i][j] = p.number
else:
# We are outside the board
break
draw_board(board)
print(board)
Upvotes: 2