How to check connect 4 for horizontal wins - python

*I am trying to find code to check if four or more 1's, or 2's are next to each other in the 2d list and then return my win function as true
Here is the code below:
# Connect Four
# 2d list
numRows = 6
numCols = 7
board = [[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, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0], ]
def printBoard():
for rows in range(0, numRows):
for cols in range(0, numCols):
print(board[rows][cols], end=' ')
print(" ")
def fillIn(col, player):
col = col - 1
for rows in range(numRows - 1, -1, -1):
if board[rows][col] == 0:
print("Legal Move")
board[rows][col] = player
break
def win():
if horizWin() or vertWin() or diagWin():
return True
return False
def horizWin():
return False
def vertWin():
return False
def diagWin():
pass
player = 1
while not win():
col = int(input("Please Select A Colum 1-7: "))
fillIn(col, player)
printBoard()
if player == 1:
player = 2
else:
player = 1
I was following a tutorial and it abruptly stopped. So any help would be greatly appreciated :)

You can do something like this.
I added some debug print statements so you understand better what is happening step by step. Dissable the prints when you are comfortable on how the code works
def horizWin():
# loop over each row in the board
for row in board:
print (f"Current row: {row}")
# take a window of size 4 and slide it over the row.
# you need to iterate from 0 to len(row)-windowsize+1
for i in range(len(row)-4+1):
window = row[i:i+4]
print(f" Current window: {window}")
# check if all elements in the row are 1s or 2s
# all elements are the same if the number of elements
# equal to the first one is the size of the window.
# you also need to check that this element is 1 or 2
if window.count(window[0]) == 4 and window[0] in (1,2):
print(f" This window has a winning position for player {window[0]}")
return True
print("No winning positions found in the board")
return False

Related

Python - highlight pattern inside a matrix

I have a simple exam to pass where I have to write a program where I create a binary matrix and a pattern and I have to find the pattern inside the matrix and to highlight it if found. I can't use any external library - specially numpy.
What I have atm are just some highlighted numbers that don't match my pattern. I don't know how to continue. Can someone help me please?
My code is this:
pattern.py:
# to create a matrix from an array of arrays
def create(n, m, data):
matrix = []
for i in range(n): #n=rows number
row = []
for j in range(m): #m=columns number
if data[j] not in matrix:
row.append(data[m * i + j])
matrix.append(row)
return matrix
# to colour the elements in 1 inside the pattern
def colora(element):
if element == 1:
element = '\u001b[36m1'
elif element == 0:
element = '\u001b[00m0'
return element
# my pattern forms an I vertically - I should also find it if horizontal
def patternI():
array = [1, 0, 0, 1, 0, 0, 1, 0, 0]
pattern = create(3, 3, array)
for i in range(3):
for j in range(3):
col_element = colora(pattern[i][j])
print(col_element, end=" ")
# print(pattern[i][j], end=" ")
print()
return pattern
main.py:
import patterns
import ricerca
# to create and print the matrix
def matrix():
m = 5
n = 5
array = [0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0]
matrix = patterns.create(n, m, array)
for i in range(n):
for j in range(m):
print(matrix[i][j], end=" ")
print()
return matrix
def main():
print("pattern:")
pattern = patterns.patternI()
print("\r")
print("matrix:")
matrice = matrix()
print("\r")
print("risult:")
newArray=ricerca.ricerca(pattern, matrice)
main()
ricerca.py:
import patterns
# to search the pattern (m_piccola) inside the (m_grande)
def ricerca(m_piccola, m_grande) :
daricordare = [] #an array to fill with the position of the matrix which combines a little with the pattern
for jR in range(len(m_piccola) - 1) :
for iR in range(len(m_grande)) :
for iC in range(len(m_grande[0])) :
for jC in range(len(m_piccola[jR])) :
if m_piccola[jR][jC] == 0 :
jC += 1
break
if m_piccola[jR][jC] == 1 :
if m_grande[iR][iC] == m_piccola[jR][jC] :
daricordare.append((iR, iC))
else :
iC += 1
data = coloraQuelliDelPattern(daricordare, m_grande)
for i in range(5):
for j in range(5):
print(data[i][j], end = " ")
print()
return data
# to highlight the numbers in the array which are inside "daricordare"
def coloraQuelliDelPattern(daricordare, array) :
for i in range(len(daricordare) - 2) :
a = daricordare[i]
b = daricordare[i + 1]
c = daricordare[i + 2]
if b[1] == a[1] + 1 and c[1]==a[1] + 2:
array[a[0]][a[1]] = "\u001b[36m1"
array[b[0]][b[1]] = "\u001b[36m1"
array[c[0]][c[1]] = "\u001b[36m1"
if b[1] != a[1] + 1 or c[1] != a[1] + 2 :
array[a[0]][a[1]] = "\u001b[00m1"
array[b[0]][b[1]] = "\u001b[00m1"
array[c[0]][c[1]] = "\u001b[00m1"
return array

Greedy Algorithms and append function - how to create a new array?

Okay, so I have an array coin and I want to create a new array which is the same length as array, but with the amount of coins from the array 'coins' needed for input m.
coin = [200,100,50,20,10,5,2,1]
So far, I have the following. What should be in for loop for me to return what I want?
def coinSplitGD2(m):
coin = [200,100,50,20,10,5,2,1]
if m==0:
return 0
for i in range(len(coin)):
if coin...
So if m is 143, it will return [0, 1, 0, 2, 0, 0, 1, 1] meaning no 200-coins, one 100-coin, no
50-coins, two 20-coins, no 10-coins, no 5-coins, one 2-coin and one 1-coin
coin = [200,100,50,20,10,5,2,1]
def coinSplitGD2(m):
a = []
for c in coin:
a.append(m // c)
m %= c
return a
so that:
coinSplitGD2(143)
returns:
[0, 1, 0, 2, 0, 0, 1, 1]

Python: use item in the list as function arguments

I have to program this puzzle and solve it (I'm using 100 coins instead of 26), and currently all I have are:
def flip():
if (coin == 0):
coin = 1
if (coin == 1):
coin = 0
def move():
table_one.remove(coin)
table_two.append(coin)
def CoinPuzzle():
table_one = [[1]*20 + [0]*80]
table_two = []
#Move 20 coins from table_one to table_two
#Flip all 20 coins in table_two
#Both tables should have an equal number of 1s
I have a hard time linking individual coin objects with items in the list so that I can execute flip and move functions. I'm new to Python, can someone guide me how to do this?
NEW EDIT: How should I modify the code if I have input like this:
L=[0]*100
for i in random.sample(range(100),20):
L[i]=1
[L1,L2]=tables(L)
Here is small python implementation:
import random
heads_count = 20
total_coins = 100
table_one = [True] * heads_count + [False] * (total_coins-heads_count)
table_two = []
def flip(table, coin):
table[coin] = not table[coin]
def move_random():
coin = random.randint(0, len(table_one)-1)
table_two.append(table_one[coin])
del table_one[coin]
for i in range(heads_count):
move_random()
for i in range(heads_count):
flip(table_two, i)
print(sum(table_one))
print(sum(table_two))
Here's an alternative to Stephen's version. To make the output easier to read I'll use the numbers from the original puzzle.
We use the shuffle function to randomize the order of the coins in table_one in a single step, then use slicing to move heads_count coins from table_one to table_two. To flip the coins, we use the fact that 1 - 0 = 1 and 1 - 1 = 0.
from random import seed, shuffle
# seed the randomizer so we get repeatable results
seed(42)
total_coins = 26
heads_count = 10
# Put all the coins in table_one and randomize their order
table_one = [1] * heads_count + [0] * (total_coins - heads_count)
shuffle(table_one)
print('Initial')
print('Table one:', table_one, sum(table_one), len(table_one))
# move heads_count coins to table_two
table_one, table_two = table_one[heads_count:], table_one[:heads_count]
#flip all the coins in table_two
table_two = [1 - coin for coin in table_two]
print('Final')
print('Table one:', table_one, sum(table_one), len(table_one))
print('Table two:', table_two, sum(table_two), len(table_two))
output
Initial
Table one: [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1] 10 26
Final
Table one: [1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1] 8 16
Table two: [1, 1, 1, 0, 0, 1, 1, 1, 1, 1] 8 10
We could even combine the last two steps into a single statement:
table_one, table_two = table_one[heads_count:], [1 - coin for coin in table_one[:heads_count]]

How to fix "list indices must be integers, not type" [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
How to fix this code:
def CheckRow(arr, row, num):
for col in range(9):
if (arr[row][col] == num):
return True
return False
TypeError: list indices must be integers, not type
row or col is not integer, one of them is a type. Check them, probably one of them is equal to None because you said it's a function in a class.
def SolveSudoku(arr):
row = int
col = int
if (not FinZero(arr, row, col)):
return True
for num in range(1,10):
if (IsSafe(arr, row, col, num)):
arr[row][col] = num
if (SolveSudoku(arr)):
return True
arr[row][col] = 0
return False
In this part you see row = int. This is the worst definition I've ever seen, probably the writer of the code tried to define an empty integer. Basically change this to row = int().
Check this
row = int
row_int = int()
print (type(row))
print (type(row_int))
Output;
>>>
<class 'type'>
<class 'int'>
>>>
See first one is type, second one is an integer.
The error is not with the code but with the input.
Most likely you passed the argument row as something other than an integer.
Your code should also be formatted like so:
def CheckRow(arr, row, num):
for col in range(9):
if (arr[row][col] == num):
return True
return False
EDIT
I reviewed the code that you linked in GLHF's post.
Conversion problems
Here is my version, keeping all your naming conventions in your C++ code.
UNASSIGNED = 0
N = 9
def FindUnassignedLocation(grid, row, col):
for row in range(N):
for col in range(N):
if grid[row][col] == UNASSIGNED:
return True
return False
def UsedInRow(grid, row, num):
for col in range(N):
if grid[row][col] == num:
return True
return False
def UsedInCol(grid, col, num):
for row in range(N):
if grid[row][col] == num:
return True
return False
def UsedInBox(grid, boxStartRow, boxStartCol, num):
for row in range(3):
for col in range(3):
if grid[row + boxStartRow][col + boxStartCol] == num:
return True
return False
def isSafe(grid, row, col, num):
return False not in (UsedInRow(grid, row, num),
UsedInCol(grid, col, num),
UsedInBox(grid, row - (row % 3), col - (col % 3), num)):
def printGrid(grid):
for row in range(N):
for col in range(N):
print "%2d" % (grid[row][col])
def SolveSodoku(grid):
row = 0
col = 0
if not FinZero(grid, row, col):
return True
for num in range(1,10):
if isSafe(grid, row, col, num):
grid[row][col] = num
if SolveSodoku(grid):
return True
else:
grid[row][col] = UNASSIGNED
return False
grid = [
[ 3, 0, 0, 0, 0, 0, 5, 0, 0 ],
[ 0, 0, 0, 8, 0, 6, 0, 0, 0 ],
[ 0, 2, 5, 0, 0, 0, 6, 0, 1 ],
[ 7, 0, 9, 0, 3, 8, 0, 0, 4 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 1, 0, 0, 9, 4, 0, 3, 0, 6 ],
[ 8, 0, 3, 0, 0, 0, 7, 6, 0 ],
[ 0, 0, 0, 3, 0, 4, 0, 0, 0 ],
[ 0, 0, 1, 0, 0, 0, 0, 0, 9 ]
]
if SolveSodoku(grid):
printGrid(grid)
else:
print "No solution exists"
The problem you had was that when converting from C++ to Python, the statement in C++
int row, col;
Would actually instantiate the variables with a default value of 0. Therefore, it is equivalent to Python's
row = 0
col = 0
Maximum Recursion Depth
This issue would be supposedly resolved in this post.
It is a guard against a stack overflow, yes.
You can change the recursion limit with sys.setrecursionlimit, but doing so is dangerous -- the standard limit is a little conservative, but Python stackframes can be quite big.
However, when you increase the maximum recursion depth, it did warn that it may crash Python (which it did on my computer), I suggest you take a look at one of the solutions to solving recursive sodoku here.

Manhattan grid directions with random walk

I am trying to write a function that takes the number or rows and columns in a grid, simulates a random walk starting in the center of the grid, and computes the number of times each intersection has been visited by the random walk. Then prints the table line by line once the random walk moves outside the grid
So far I have this but i cant get it to work right.
def manhattan(x,y):
'int,int==>nonetype'
import random
res=[]
for i in range(x):
res.append([])
for i in res:
for j in range(y):
i.append(0)
position=(x//2+1,y//2+1)
z=position[0]
v=position[1]
while z!=-1 or z!=x or v!=-1 or v!=y:
direction=random.randrange(1,5)
if direction==1:
v+=1
elif direction==2:
z+=1
elif direction==3:
v-=1
else:
z-=1
for i in range(len(res)):
if i ==z:
res[i]+=1
for j in range(i):
if v==j:
i[j]+=1
for i in res:
print(i)
It should read when done:
manhattan(5,11)
[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,1,1,1,2,2]
[0,0,0,0,0,0,0,0,0,0,0]
[0,0,0,0,0,0,0,0,0,0,0]
You were very close, try the following:
def manhattan(x,y):
'int,int==>nonetype'
import random
res=[]
for i in range(x):
res.append([])
for i in res:
for j in range(y):
i.append(0)
position=(x//2+1,y//2+1)
z=position[0]
v=position[1]
while z!=-1 and z!=x and v!=-1 and v!=y:
res[z][v] += 1
direction=random.randrange(1,5)
if direction==1:
v+=1
elif direction==2:
z+=1
elif direction==3:
v-=1
else:
z-=1
for i in res:
print(i)
Nothing is different until the while loop, and there are only a couple of changes. First you need to use and instead of or in the loop condition check since you want to exit if any of those conditions are met.
The other change was to remove the for loop from the bottom of the while loop and replace it by res[z][v] += 1, this works because z and v represent the intersection and you already initialized res to be a two-dimensional list of all the intersections so looping is unnecessary. I also moved this up to the top of the loop because otherwise you might try to modify res after moving past the boundary.
Here is a bit less verbose version that uses random.choice instead of your chained elif statements. I found it helpful when learning python to see the same problem in different ways, so here is a pure python and a numpy + python implementation.
Pure Python
import random
def manhattan(n,m):
grid = [[0,]*m for _ in xrange(n)]
directions = [[-1,0],[1,0],[0,-1],[0,1]]
pt = [n//2, m//2]
while pt[0]>=0 and pt[0]<n and pt[1]>=0 and pt[1]<m:
grid[pt[0]][pt[1]] += 1
d = random.choice(directions)
pt[0] += d[0]
pt[1] += d[1]
return grid
for row in manhattan(5,11):
print row
This gives, for example,
[0, 0, 0, 1, 3, 3, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 3, 3, 2, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0]
[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0]
Python + numpy
import numpy as np
import random
def manhattan(n,m):
grid = np.zeros((n,m),dtype=int)
directions = [[-1,0],[1,0],[0,-1],[0,1]]
pt = np.array([n//2, m//2])
while (pt>=0).all() and (pt<grid.shape).all():
grid[pt[0],pt[1]] += 1
pt += random.choice(directions)
return grid
print manhattan(5,11)

Categories