P: 8

Hi,
This time I'm trying to make a tic tac toe game. I'm trying to make a game where player is able to choose the size of the board and how many marks is needed in line to win.
I have created a m*n sized board like this: 
import numpy


def new_board(m,n):

row = []

rows = []

for i in range(n):

element = '_'

row.append(element)

for i in range(m):

rows.append(row)

board = numpy.array(rows)

return board


def main():

m = input('Rows: ')

n = input('Columns: ')

board = new_board(m,n)

.

.

.


main()

My problem is that I can't make a function that sets the winning conditions and a function that checks them. This is very hard because there is infinite amount of winning conditions in m*n board where you need k marks in line to win. Can anyone give me any help?
 
Share this Question
Expert Mod 2.5K+
P: 2,851

You would only check for a winning condition after a board position is selected. There are 4 directions to check:
left to right (row)
top to bottom (column)
diagonal (row+, column+)
diagonal (row+, column)
I would set up the board as a class object with an instance method to determine the necessary adjacent positions, and maybe another method to determine if the winning number of adjacent positions are occupied by a player. I am not convinced numpy is necessary, but I have never used it.
 
P: 8

I'm using numpy only because of with it that table could be printed in very nice form and still it could be used like list. I think that there is surely a better way to do it, but as I am pretty new to python this way seemed best for me :)
Bvdet, you suggested making the board for a class object and also that instance method to determine those necessary adjacent positions. Can you tell me what are class objects and how to make that board into one? Also can you be more specific with that method? So far I have used very much loops for coding and those other commands aren't very familiar to me. That's also one reason why I'm trying to make this game to work with functions so that I could finally get rid of complicated "for in", "while" and "if" structures. :)
  Expert 100+
P: 469

If you're not familiar with classes, you probably would be better off not using them. They are a big thing to learn about. But to check whether a player has won, what you could do is:  Count the number of pieces above the played piece.

Count the number of pieces below it.

If the sum of those numbers is high enough, then the player has won.

Otherwise:

Count the number of pieces to the left of the played piece.

Count the number of pieces to its right.
and so on.
To find the number of pieces in a certian direction from a piece, you could use a loop that counts the pieces until it finds a square without a piece.
You might be able to create a function that counts the number of pieces in a specified direction to make this more compact.
I hope this is helpful.
  Expert Mod 2.5K+
P: 2,851

I think boxfish is right about not attempting to write it as a class since you are not familiar with them. For general definition, a class defines a set of attributes associated with objects known as instances. An instance is created by calling a class object as you would call a function. A good example would be a point object. A point could be created similar to this:
An instance (p1 in this case) will have properties and methods that were defined in the class object and contain data and perform operations. These are called attributes. An example of the use of a method would be to calculate the distance between 2 point objects or return the unit vector. Examples of data attributes are X, Y, and Z coordinates.  >>> p2 = Point(1,1,1)

>>> p1.dist(p2)

1.7320508075688772

>>> p2.uv()

Point(0.577350, 0.577350, 0.577350)

>>> p1.x

0.0

>>> p2.z

1.0

>>>
You should be able to reach your goal with functions. I have an example to get the adjacent (n1) elements of a list.  >>> def get_adj_items(itemList, col, n=3):

... return itemList[max(0,col(n1)):col]+itemList[col:min(len(itemList),col+n)]

...

>>> get_adj_items([0,1,2,3,4,5,6,7,8,9,0], 4, 3)

[2, 3, 4, 5, 6]

>>> get_adj_items([0,1,2,3,4,5,6,7,8,9,0], 4, 4)

[1, 2, 3, 4, 5, 6, 7]

>>> get_adj_items([0,1,2,3,4,5,6,7,8,9,0], 1, 4)

[0, 1, 2, 3, 4]

>>>
That would narrow it down in determining if consecutive items are the same.
 
P: 8

Phew, I finally managed to make that algorithm. Maybe it's not the best way to do such checkfunction, but at least this works well for infinite board. I made different algorithms for rows, columns and diagonals. Here's that code:
Here m represents the number of rows, n number of columns and k number of adjacent marks needed to win the game. 
def Row(board, m,n, k, mark):

counter = 0

for i in range(m):

for j in range(n):

if board[i][j] == mark:

counter += 1

if j == n1 and counter != k:

counter = 0

elif counter == k:

return True

else:

counter = 0

return False


def Columns(board,m,n,k,mark):

counter = 0

for i in range(n):

for j in range(m):

if lauta[j][i] == mark:

counter += 1

if j == n1 and counter != k:

counter = 0

elif counter == k:

return True

else:

counter = 0

return False


def DiagonalUp(board,m,n,k,mark):

counter = 0

for i in range(m):

for j in range(n):

if board[i][j] == mark:

counter += 1

if counter == k:

return True

else:

counter = 0

i = 1

j += 1

if i == 1 or j == n:

counter = 0

return False



def DiagonalDown(board, m, n, k, mark):

counter = 0

for i in range(m):

for j in range(n):

if board[i][j] == mark:

counter += 1

if counter == k:

return True

else:

counter = 0

i += 1

if i == m:

i = 0

counter = 0

elif j == n:

j = 0

return False


def winner(board,mark,k, win,m,n):

R = Row(board,m,n,k,mark)

C = Columns(board,m,n,k,mark)

DU = DiagonalUp(board,m,n,k,mark)

DD = DiagonalDown(board,m,n,k,mark)

if R == True or C == True or DU == True or DD == True:

win = 0

return win

else:

win = 1

return win

  Expert 100+
P: 469

Does your program still detect a win if you get more than k pieces in a row?
Edit:
I think it does; never mind.
 
P: 8

Yes it does. That program checks if there are at least k pieces in a row, so if there are more it doesn't matter. But instead of that I found one mistake: If board size is rows:m and columns:m+2(or more), that checker wont work at all. If number of columns is rows + 1 or same as rows it will work. Also if there are more columns than rows it will work too. Now i need to check out where is that mistake and try to fix it.
    Question stats  viewed: 3812
 replies: 7
 date asked: Nov 25 '08
