So I'm trying to implement a ConnectFour game in python, and I'm having some trouble with counting the pieces (from a single player) that are lined up together in a row. My code:
class ConnectFour(object):
def __init__(self):
self.row=6
self.col=7
self.board = []
#initialize the board
for arow in range(self.row):
row = []
for acol in range(self.col):
row.append(None)
self.board.append(row)
#function for counting the number of the same pieces in a row
def count_it(self, row, column, step_row, step_col):
assert row >= 0 and row < 6 and column >= 0 and column < 7
assert step_row != 0 or step_col != 0
counter1 = 0
counter2 = 0
if self.board[row][column] == None:
return 0
elif self.board[row][column] == 1:
for i in range(6):
while self.board[row + (i*step_row)][column + (i*step_col)] == 1:
counter1 += 1
return counter1
else:
for i in range(6):
while self.board[row + (i * step_row)][column + (i*step_col)] == 2:
counter2 += 1
return counter2
When I input a location and "step" in my function, I would like to get the number of pieces player 1 or player 2 has lined up but when I enter:
x= ConnectFour()
x.board[5][6] = 1
x.board[4][6] = 1
x.count_it(5,6,-1,0)
I get no output.
There is no need for that while inside for: whenever the while condition is true, it will become an infinite loop since the body of that loop does not affect the condition, it just keeps incrementing a counter forever.
One approach would be a single while loop:
while self.board[row + (counter1*step_row)][column + (counter1*step_col)] == 1:
counter1 += 1
Another approach is to leave the for loop, but i and counter1 actually serve the same purpose:
for i in range(6):
if self.board[row + (i*step_row)][column + (i*step_col)] != 1:
break
counter1 += 1
In both cases, take care of array boundaries, either by some ifs, or by placing sentinels at the border of the array.
Related
I am making a piece of code that generates bingo cards. It makes sure that there are going to be 5 numbers on each horizontal row and that each vertical column has the numbers between 1-9, 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70-79, and 80-90. However the list values never has anything appended to it, so it can never get to the next loop. Here is the code:
def generate_nums(nums): #nums looks like this: [[],[],[]] - which is how it is inputed
for i in range(0, len(nums)):
while True:
values = []
Min = 1
Max = 9
counter = 0
for j in range(0, len(nums[i])):
value = random.randint(0, 1)
values.append(value)
if value == 1:
counter += 1
if counter == 5:
for item in values:
if item == 1:
nums[i].append(random.randint(Min, Max))
else:
nums[i].append(" ")
if Min == 1:
Min = 10
else:
Min += 10
if Max == 79:
Max = 90
else:
Max += 10
break
#Function call
if __name__ == "__main__":
nums = [[],[],[]]
print(generate_nums(nums))
Any help is appreciated, I am only looking to improve my knowledge as I am doing computer science GCSE and I love python and the challenges it presents, though I don't know what to do here.
Thanks!
So I have a simple piece of code:
class Player:
def __init__(self):
self.score = 0
players = [Player() for _ in range(10)]
Now I want to:
Iterate the players in the list indefinitely
Skip players with a negative score
from itertools import cycle
loop = cycle(players)
loop = filter(lambda player: player.score >= 0, loop)
Stop the iteration when there is only one player left with a positive score
Or when there are two or more players with a positive score, every one of them has been iterated at least once and each of them has an equal score
I have a problem with these conditions and I don't know how to bite them.
Solution 1
Here's a solution using mostly itertools.
import itertools
positive_players = lambda : filter(lambda player: player.score >= 0, players)
loop = itertools.cycle(positive_players())
if len(list(positive_players())) <= 1:
loop = positive_players()
if len(set([p.score for p in positive_players()])) <= 1:
loop = positive_players()
Some tests:
3 players, all have score zero: stops after one loop.
3 players with scores [0, 42, 0]: continues forever
3 players with scores [-1, 42, -2]: stops after printing the one positive player.
Solution 2
Here's an alternative solution, using a generator.
def loop_players(players):
inx = 0
positive_count = 0
positive_scores = set()
while True:
p = players[inx]
inx += 1
if p.score < 0:
continue
positive_count += 1
positive_scores.add(p.score)
yield p
if inx == len(players):
inx = 0
if positive_count < 2:
break
if len(positive_scores) < 2:
break
i = 10
while i>=1:
print("count down in " + str(i))
i = i - 1 #or i +=1
if i<10:
print("blasting off")
if i==0:
print("ready in " +str(i))
while i<=10:
print("starting up in " + str(i))
i +=1
how to reloop this endlessly like 10 to 0 than 0 to 10 forever
Put your two loops inside an infinite outer loop, for example:
while True:
for i in range(10,1,-1):
print(i)
for i in range(1,10):
print(i)
In python there is an easy way to do endless cycles. You can use the while(True), which will be always true. I hope this helped.
i = 10
temp = True
while(True):
i = 10
while i>=1:
print("count down in " + str(i)
i -= 1
if i<10:
print("blasting off")
if i==0:
print("ready in " +str(i))
while i<=10:
print("starting up in " + str(i))
i +=1
count_up = 0
count_down = 10
while True:
count_up += 1
count_down -= 1
print("Count_up: ", count_up)
print("Count_down:", count_down)
if count_up == 10: # once it counts up to 10 reset to 0
count_up = 0
if count_down == 0: # once it dounts down to 0 reset to 10
count_down = 10
This will go up 10 and down 10 endlessley
or if you just want to use 1 variable in this case i:
i = 10
while True:
print(i)
i -= 1
if i == 0:
for j in range(10):
print(i)
i += 1
This one here uses a generator, which is a construct in python that yields values whenever asked for the next one. The cool thing about it is that you can separate your value generation logic from your other code using these values (even if it's just a print). This helped me before in cases where the code got too entangled to understand easily.
def triangle(vmax):
""" Generator that yields values of a periodic triangle function between 0 to vmax,
starting at vmax. """
# init states
v = vmax - 1 # the last generated value
rising = True # indicates the current direction
# now yield values forever
while True:
if v == vmax:
rising = False
elif v == 0:
rising = True
v += 1 if rising else -1
yield v
t = triangle(10) # create the generator...
vals = [next(t) for i in range(30)] # ... now get 30 values from it
print(vals)
I'm trying to make a program which adds the player's input to a list that's sorted alphabetically. When I try the program I've come up with it just arranges the words haphazardly, and I don't know whatäs wrong. What am I missing? I am fully aware there's a function which sorts for you, I'm simply doing this for practice.
alphabet = 'abcdefghijklmnopqrstuvwxyz'
array = []
while True:
pl_inp = input('Add something to the list:\n')
location = 0
list_has_content = False
for x in reversed(array):
indx = 0
if alphabet.find(pl_inp[indx]) == alphabet.find(x[indx]):
indx += 1
elif alphabet.find(pl_inp[indx]) > alphabet.find(x[indx]):
list_has_content = True
location = array.index(x)
elif alphabet.find(pl_inp[indx]) < alphabet.find(x[indx]):
location = array.index(x) + 1
break
if location == 0 and list_has_content == True:
array.insert(location, pl_inp)
elif location > 0:
array.insert(location, pl_inp)
else:
array.append(pl_inp)
print(array)
I have written a code using recursion, but later realized that the depth is too high and does not work for higher level input values. It works completely fine without any issue.
def checkCount(first_window, index=0,reference_list=None):
reference_list = []
count = 0
while index<=len(first_window)-2:
if first_window[index] < first_window[index+1]:
index += 1
count += 1
else: break
if count != 0:
reference_list.append(int((count*(count+1))/2))
count = 0
while index <= len(first_window)-2:
if first_window[index] > first_window[index+1]:
index += 1
count += 1
else: break
if count != 0:
reference_list.append(-int((count*(count+1))/2))
if index > len(first_window)-2: return reference_list
elif first_window[index] == first_window[index+1] and index<len(first_window)-2: index += 1
reference_list = reference_list + checkCount(first_window, index, reference_list)
return reference_list
import random
import time
start = time.clock()
input_array = list(map(int,"188930 194123 201345 154243 154243".split(" ")))
input_array = random.sample(range(1,100),10)
def main():
N = len(input_array)
K = 8
if K == 1: return None
print("Input array: ",input_array)
print("First Window",input_array[:K])
print("Real Output", checkCount(input_array[:K]))
if __name__ == "__main__":main()
Now no matter how I try without recursion, it ends with an infinite loop. I have tried different ways but no progress.
One way I have tried is taking out the recursion statement and returning the referencelist + index:
def checkCount(..):
....
....
return referencelist,index
while index <= K-2:
print("While",index)
reference_list, index = checkCount(new_input, index=0, reference_list=[])
referencelist += reference_list
The application is similar to the here. But we have to deal with tons of data where recursion cannot help. Assume that the input array is greater than 100,000. I am really struck here, I do not understand what logic am I missing. Any help will be grateful.
The first_window variable is only read, and the index variable is only incremented. There is no need for recursion, a simple loop can work.
def check_count(first_window):
reference_list = []
index = 0
while index < len(first_window) - 2:
count = 0
while index <= len(first_window) - 2:
if first_window[index] < first_window[index + 1]:
index += 1
count += 1
else:
break
if count != 0:
reference_list.append(int((count * (count + 1)) / 2))
count = 0
while index <= len(first_window) - 2:
if first_window[index] > first_window[index + 1]:
index += 1
count += 1
else:
break
if count != 0:
reference_list.append(-int((count * (count + 1)) / 2))
if index < len(first_window) - 2 and first_window[index] == first_window[index + 1]:
index += 1
return reference_list
Of course, this algorithm can be optimised, for instance, we can avoid repetitions like: len(first_window) - 2.