Related
I am trying to prevent the user from inputting a square that is already marked, but the for loop moves on to the next player's input without decrementing the value of i by one, so the player 1 can repeat his input. How do I fix this?
arr = [[0,0,0],[0,0,0],[0,0,0]]
grid = grid(arr)
grid.print_grid()
for i in range(9):
row = int(input("Enter the row name: "))
col = int(input("Enter the column name: "))
if(arr[row][col] == 0):
if(i%2):
arr[row][col] = 1
else:
arr[row][col] = 2
else:
print("\nThat square has already been marked! Please select another square")
i = i-1
continue
grid.print_grid()
res = grid.grid_checker()
if (res == 1):
print("\nPlayer 1 wins the game!")
break
elif(res == 2):
print("\nPlayer 2 wins the game!")
break
elif(i == 8):
print("\nThe game has ended in a draw!")
You need to store another variable to keep track of whose turn it is. You cannot modify the variable you are looping on while you are in the loop body. This means that i cannot be manipulated while you are running in the loop. Here's how I would change it.
turn = 0
while True:
row = int(input("Enter the row name: "))
col = int(input("Enter the column name: "))
if(arr[row][col] == 0):
if(i%2):
arr[row][col] = 1
turn = turn + 1
else:
arr[row][col] = 2
turn = turn + 1
else:
print("\nThat square has already been marked! Please select another square")
continue
grid.print_grid()
res = grid.grid_checker()
if (res == 1):
print("\nPlayer 1 wins the game!")
break
elif(res == 2):
print("\nPlayer 2 wins the game!")
break
elif(turn == 8):
print("\nThe game has ended in a draw!")
Here we're saving the turn number in the variable turn and only incrementing the variable when we can confirm a player has successfully completed their turn.
Why you cannot modify i: For optimisations, loops are often expanded by python before they are converted to assembly instructions. For example a simple loop like this:
for i in range(9):
print(i)
May be expanded to something like this:
i = 0
print(i)
i = 1
print(i)
# and so on, upto
i = 9
print(i)
This is done to avoid having to jump around in memory. So as you can see here, i is reassigned for every iteration of the loop. Therefore, even if you change the value of i in the body of the loop, it will simply be reassigned before the next iteration.
I'm a fairly new programmer, but I am trying to make a fighting game code, but I have been stumped on one part, within my code I am trying to make sure that when the enemy health = 0, it will end. I can make the program end, well. But I don't want to enemy health to go under 0, it can work with me fine, but I really want to change this.
import random
gameactive = 0
x= 100
while gameactive == 0:
if x > 0:
crit = random.randint(8,9)
base = random.randint(5,6)
a = random.randint(1,10)
if a == 10:
x -= crit
print("\nITS A CRITICAL HIT!") # Dont mind this please, this chunk about critical hits.
print("\n")
print(str(x) + " Health left")
else:
x -= base
print("\n")
print(str(x) + " Health left")
else:
break
so what happens when the program is ran, it will generate numbers and decreases x using those generated numbers. But when running the program, I want the code to only limit itself 0 health and not go under.
Sorry if i horribly explained it simply put, I want a way so x will be capped at 0, and it will not print negative numbers and instead print some sample text like enemy died.
use max function like t his:
import random
gameactive = 0
x= 100
while gameactive == 0:
if x > 0:
crit = random.randint(8,9)
base = random.randint(5,6)
a = random.randint(1,10)
if a == 10:
x -= crit
print("\nITS A CRITICAL HIT!") # Dont mind this please, this chunk about critical hits.
else:
x -= base
print("\n")
print(str(max(x,0)) + " Health left")
else:
break
One way would be to change where you print "x Health left". So in the code below, at each iteration the value of x will be reported before the hit, until x goes below zero, in which case the custom message "x died" or similar can be printed, and the loop breaks.
while gameactive == 0:
if x > 0:
#report current health here, before hit
print(str(x) + " Health left")
crit = random.randint(8,9)
base = random.randint(5,6)
a = random.randint(1,10)
if a == 10:
x -= crit
print("\nITS A CRITICAL HIT!") # Dont mind this please, this chunk about critical hits.
print("\n")
else:
x -= base
print("\n")
else:
#x died
print("x died.")
break
I am creating a simple game that takes a user input (either 0 or 1) and compares it to the computer input. Depending on the input of the user in the previous moves, the computer will take the decision to play 0 or 1.
select_difficulty = int(input("Choose the type of game (1: Easy; 2: Difficult): "))
moves = int(input("Enter the number of moves: "))
MS = 0
PS = 0
xi = 1234
throw00 = []
throw01 = []
throw10 = []
throw11 = []
The conditions are the following:
throw00 = count of the number of times the human player chose 0 given that in the previous move he chose 0
throw01 = count of the number of times the human player chose 0 given in the previous move he chose 1
throw10 = count of the number of times the human player chose 1 given that his previous move was 0 throw11 = count of the number of times the human player chose 1 given his/her previous bid was 1
the following cases may occur:
If the player's last throw was 0:
If throw10 > throw00: then the computer chooses 1
If throw10 < throw00: then the computer chooses 0
If throw10 = throw00: then the computer chooses randomly 0 or 1
If the player's last throw was 1:
If throw11 > throw01: then the computer chooses 1
If throw11 < throw01: then the computer chooses 0
If throw11 = throw01: then the computer chooses randomly 0 or 1.
I've tried to this by saving the player move in a list and then access the previous move (one turn later) from that list.
if select_difficulty == 2:
for turn in range(moves):
player_move_dif = [int(n) for n in input("Choose your move number %s (0 or 1):" % (turn+1)).split()]`
player_previous_move = player_move_dif[1]
Based on these two variables on these two variables I then append the player_move choices (0 or 1) to the respective list which is in turn used by the "computer" to choose his move
if player_move_dif == 0 and player_previous_move == 0:
throw00.append(player_move_dif)
elif player_move_dif == 0 and player_previous_move == 1:
throw01.append(player_move_dif)
elif player_move_dif == 1 and player_previous_move == 0:
throw10.append(player_move_dif)
else:
throw11.append(player_move_dif)
#define computer behavior depening on previous player move
if player_previous_move == 0:
if len(throw10) > len(throw00):
computer_move = 1
elif len(throw10) < len(throw00):
computer_move = 0
else:
computer_move,xi = linear_congruence(xi)
elif player_previous_move == 1:
if len(throw11) > len(throw01):
computer_move = 1
elif len(throw11) < len(throw01):
computer_move = 0
else:
computer_move,xi = linear_congruence(xi)
else:
computer_move,xi = linear_congruence(xi)
this does not work since I need the values from the player moves (as integers) for print statements to show how the game goes on
if player_move_dif == computer_move:
MS = MS + 1
print("player = %d machine = %d - Machine wins!" % (player_move_dif, computer_move))
print("You: %d Computer: %d" % (PS, MS))
else:
PS = PS + 1
print("player = %d machine = %d - Player wins!" % (player_move_dif, computer_move))
print("You: %d Computer: %d" % (PS, MS))
print('PLAYER: ' + '*'*PS)
print('MACHINE: ' + '*'*MS)
if turn == moves and PS > MS:
print("The game has ended, you win!")
elif PS == MS:
print("The game has ended, it is a draw!")
else:
print("the game has ended, the machine wins!")
this way this currently results in a TypeError %d format: a number is required, not list. I suspect I am on the wrong path how to solve this the way I'm trying now as I cannot find solution to define the variables the way I want to while simultaneously be able to access them later as needed.
Besides i'm not sure if the logic of the game is implemented correctly, i found some issues which led to your error.
If you want to save the player's move into a list, you have to create an empty list before the for loop, otherwise you overwrite it again and again. Also you got the problem, that there are no previous moves at the very first move, so you need a start number at first:
player_move_dif = [] #create an empty list out of your for-loop
for i, turn in enumerate(range(moves)): #use enumerate() to count the loops
if i > 0: #first move has no previous one
player_move_dif.append(input("Choose your move number %s (0 or 1):" % (turn+1)).split()))
player_previous_move = int(player_move_dif[i-1])
else:
player_move_dif.append(input("Choose your start number %s (0 or 1):" % (turn+1)).split()))
continue #no action after the first move
Then you can access the current moves by an index of your move list. In your case the last index of your list is the last move the player did:
if player_move_dif == computer_move:
MS = MS + 1
print("player = %d machine = %d - Machine wins!" % (int(player_move_dif[-1]), computer_move)) #pick the last move from play_move_dif
print("You: %d Computer: %d" % (PS, MS))
else:
PS = PS + 1
print("player = %d machine = %d - Player wins!" % (int(player_move_dif[-1]), computer_move)) #pick the last move from play_move_dif
print("You: %d Computer: %d" % (PS, MS))
*Q.Randomly generate a 4-digit number. Ask the user to guess a 4-digit number. For every digit that the user guessed correctly in the correct place, they have a “cow”. For every digit the user guessed the number in the wrong place is a “bull.”
Every time the user makes a guess, tell them how many “cows” and “bulls” they have. Once the user guesses the correct number, the game is over. Keep track of the number of guesses the user makes throughout the game and tell the user at the end.*
**Now, the problem is that I've made the program but it could generate any 4 - digit number, and that's when the problem arises. For example:
The generated number is 3568.
The user types: 3266
Then user gets 2 Cows And 2 Bulls.
But the user has no way of knowing which are the correct numbers in the number that he typed.
I want a function that can tell the user the numbers that he guessed right.
In the example, the program should tell the user that 3 and 6 are correct in the following places.**
import random
def compare_number(number, user_guess):
cowbull = [0, 0]
for i in range(len(number)):
if number[i] == user_guess[I]:
cowbull[1] += 1
else:
cowbull[0] += 1
return cowbull
if __name__ == "__main__":
playing = True
number = str(random.randint(1000, 10000))
guesses = 0
print("Let's Play A Game Of Cows And Bulls!")
print("I Will Generate A 4 Digit Number, And You Have To Guess The Numbers One Digit At A Time.")
print("For Every Number I The Wrong Place, You Get A Bull. For Every Number In The Right Place,
You Get A Cow.")
print("The Game Will End When You Get 4 Bulls.")
print("Type Exit At Any Prompt To Exit!")
while playing:
user_guess = input("Give Me The Best You Got!: ")
if user_guess.lower() == "exit":
break
cowbull_count = compare_number(number, user_guess)
guesses += 1
print(f"You Have {cowbull_count[1]} Cows, And {cowbull_count[0]} Bulls.")
if cowbull_count[1] == 4:
playing = False
print(f"You Win The Game After {guesses} Guess(es)!. The Number Was {number}.")
break
else:
print(f"Your Guess Isn't Quite Right, Tyr Again!.")
You can do something like this:
import random
def compare_number(number, user_guess):
cowbull = [0, 0, 0, 0]
for i in range(len(number)):
if number[i] == user_guess[i]:
cowbull[i] += 1
return cowbull
if __name__ == "__main__":
playing = True
number = str(random.randint(1000, 10000))
guesses = 0
print("Let's Play A Game Of Cows And Bulls!")
print("I Will Generate A 4 Digit Number, And You Have To Guess The Numbers One Digit At A Time.")
print("For Every Number I The Wrong Place, You Get A Bull. For Every Number In The Right Place, You Get A Cow.")
print("The Game Will End When You Get 4 Bulls.")
print("Type Exit At Any Prompt To Exit!")
while playing:
user_guess = input("Give Me The Best You Got!: ")
if user_guess.lower() == "exit":
break
cowbull_count = compare_number(number, user_guess)
guesses += 1
correct = sum(cowbull_count)
wrong = len(number) - correct
print(f"You Have {correct} Cows, And {wrong} Bulls.")
if correct == 4:
playing = False
print(f"You Win The Game After {guesses} Guess(es)!. The Number Was {number}.")
break
else:
print(f"Your Guess Isn't Quite Right, Try Again!.")
if correct >= 1:
print(str([user_guess[i] for i, x in enumerate(cowbull_count) if x == 1]) + " was correct!")
Changes made to your original code:
Instead of returning [numOfCorrect,numOfWrong], i returned [is 1 correct?, is 2 correct?, is 3 correct? is 4 correct?] // you need this to know which was right and which was wrong
the number of cows is = the number of correct which is equal to sum of 1's in cowbull_count //changed because of different return of compare_number
the number of bulls is = the number of wrong which is equal to number of digits - number of wrongs = len(numbers) - correct //changed because of different return of compare_number
if not all 4 digits were correct, show them which number they got correct // this is what you wanted
Sample run
You can replace your compare number function to print the index and value of the correct number.
def compare_number(number, user_guess):
cowbull = [0, 0]
for i in range(len(number)):
if number[i] == user_guess[I]:
cowbull[1] += 1
print("The number " + number[i] + " at index " + i " is correct")
else:
cowbull[0] += 1
print("The number " + number[i] + " at index " + i " is incorrect")
return cowbull
Add another method that return a list of positions: 4 element list, 0 if the user didn't guess a digit, 1 if he did. You can use it as you want in your function.
def digit_position(number, user_guess):
right_guesses = [0, 0, 0, 0]
for i in range(len(number)):
if number[i] == user_guess[i]:
right_guesses[i] = 1
return right_guesses
# Cow and Bull Game is a game in which User
# tries to guess the Secret code chosen by computer.
# We have 2 use cases i.e
# If Value in index of both User's and Computer's number are same than it is Cow.
# If Value Exists but not on same index as computer's than ita a Bull.
import random
# Following function generate a unique 4-digit number
def checkDuplication():
r = str(random.randint(1000, 9999))
for i in r:
if r.count(i) > 1:
return checkDuplication()
return r
# Following function check both number and returns Cow and Bull COUNTS.
def cowBullGame(human):
cow_count = bull_count = 0
for i in human:
if i in computer:
if human.count(i) > 1:
print('No Repeatative Numbers Allowed!')
return 0
if human.index(i) == computer.index(i): # Checking if both the value in index i are same or not
cow_count += 1
else:
bull_count += 1
print(str(cow_count)+' Cows, '+str(bull_count)+' Bulls')
return cow_count # Returning Cow_Count to check All Numbers are on right place.
computer = checkDuplication()
print(computer)
guesses = 1
# Infinite Loop till user gets 4 Cow_Counts
while True:
human = str(int(input('Guess a Number :')))
if cowBullGame(human) == 4:
print('Game Over. You made '+str(guesses)+' guesses')
break
guesses += 1
Hello I am a grade 11 student taking a grade 12 computer class coding in python. I am trying to figure out how many moves it would take for a knight to capture the king from any given space on a 8 by 8 grid. I have already written the code to solve the problem using recursion, but now I am stuck with the problem of what the maximum moves it would take to get from any given square because it runs slower the move cases I have to check. I have found similar problems on stack overflow but nothing that answers my question. If you would like to see the code please just ask. Thank you for any responses it is greatly appreciated. This is the problem i am trying to solve:
In the game of chess, there is a piece called a knight. The knight moves in an L-path, by moving two spaces in one direction and then one space in a 90O direction.
An 8x8 chess board can be defined as a 2-D list where the top left corner is (1,1), and the bottom right corner is (8,8).
In this problem, you are given a text file, knight.txt, that contains six lines of information. The first line contains the position of the king on the chessboard. The next five lines contains the position of a knight on the chess board. Your task is to calculate home many moves it takes the knight to capture the king.
For example, if the text file knight.txt contains the following:
(6,3)
(4,4)
(6,6)
(4,1)
(2,5)
(5,7)
the output of your program could look as follows:
Knight Moves
It takes 1 moves for the knight at (4,4) to capture the king at (6,3).
It takes 3 moves for the knight at (6,6) to capture the king at (6,3).
It takes 4 moves for the knight at (4,1) to capture the king at (6,3).
It takes 2 moves for the knight at (2,5) to capture the king at (6,3).
It takes 3 moves for the knight at (5,7) to capture the king at (6,3).
The code i have written so far:
print "Knight Moves"
print "------------\n"
#This function will try to find the shortest route to the king usi
def findDaKing(knightX,knightY,moveNum):
#Checks if the king and knight are on the same spot
if knightX <0 or knightX >7 or knightY <0 or knightY >7:
pass
elif chessBoard[knightY][knightX] == 1:
return moveNum
#finds if it has moved 10 times so i doesnt hit max resuresion depth or waste time
if moveNum == 6:
return -1
#moves the knight
else:
#uses resursion so because i don't know how else to do it :)
#finds the shorts route for each path and compares them
shortestRoute = findDaKing(knightX+2,knightY-1,moveNum+1)
temp =findDaKing(knightX+2,knightY+1,moveNum+1)
#checks if it found a route
if temp == -1:
pass
elif temp==1 or shortestRoute ==1:
return 1
#checks if the first one found a path and if not temp must be a shorter route or if its bigger than temp
elif shortestRoute == -1 or shortestRoute> temp:
shortestRoute = temp
temp =findDaKing(knightX+1,knightY-2,moveNum+1)
#checks if it found a route
if temp == -1:
pass
elif temp == 1:
return 1
#checks if the first one found a path and if not temp must be a shorter route or if its bigger than temp
elif shortestRoute == -1 or shortestRoute> temp:
shortestRoute = temp
temp =findDaKing(knightX+1,knightY+2,moveNum+1)
#checks if it found a route
if temp == -1:
pass
elif temp == 1:
return 1
#checks if the first one found a path and if not temp must be a shorter route or if its bigger than temp
elif shortestRoute == -1 or shortestRoute> temp:
shortestRoute = temp
temp =findDaKing(knightX-1,knightY+2,moveNum+1)
#checks if it found a route
if temp == -1:
pass
elif temp == 1:
return 1
#checks if the first one found a path and if not temp must be a shorter route or if its bigger than temp
elif shortestRoute == -1 or shortestRoute> temp:
shortestRoute = temp
temp =findDaKing(knightX-2,knightY+1,moveNum+1)
#checks if it found a route
if temp == -1:
pass
elif temp == 1:
return 1
#checks if the first one found a path and if not temp must be a shorter route or if its bigger than temp
elif shortestRoute == -1 or shortestRoute> temp:
shortestRoute = temp
temp =findDaKing(knightX-2,knightY-1,moveNum+1)
#checks if it found a route
if temp == -1:
pass
elif temp == 1:
return 1
#checks if the first one found a path and if not temp must be a shorter route or if its bigger than temp
elif shortestRoute == -1 or shortestRoute> temp:
shortestRoute = temp
temp =findDaKing(knightX-1,knightY-2,moveNum+1)
#checks if it found a route
if temp == -1:
pass
elif temp == 1:
return 1
#checks if the first one found a path and if not temp must be a shorter route or if its bigger than temp
elif shortestRoute == -1 or shortestRoute> temp:
shortestRoute = temp
#returns the shortest Route
return shortestRoute
#checks if the format is right
def checkFormat(string):
#checks if its the right len
if len(string) !=5:
return True
#checks if it has the right syntax
elif string[0] != "(" and string[4] != ")" and string[2] == ",":
return True
#checks if they are numbers
elif not(string[1].isdigit()) and not(string[3].isdigit()):
return True
#else returns false so I know that it is the right format.
return False
#This will be used to check if the text file failed to open
textFileFail = False
#trys to read from the text file
try:
chessTextFile = [line.rstrip("\n") for line in open("knight.txt")]
except:
#Prints that the text file failed and set the program no to run
print "The text file failed to open."
textFileFail = True
#This will be the 2-d list that holds the board
chessBoard = [ [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,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0]
]
if textFileFail == False:
#runs through all the lines in the text file
for line in range(0,len(chessTextFile),1):
#checks the format of the chess point
Format = checkFormat(chessTextFile[line])
#if the format error is true it failed to read it
if Format == True:
#print that it didnt work and what line the error was on
print "Sorry the format for line",line+1,"was incorrect."
#If it happened on the first line the reset of the program wont work so it just breaks else it continues in hopes of some working
if line == 0:
break
else:
continue
#if its the first one I know its the kings x and y
if line == 0:
#sets the x and y based on the string in the list
chessBoard[int(chessTextFile[line][3])][int(chessTextFile[line][1])] = 1
#Else I know its a starting point
else:
#prints how many moves it will take
print "It takes",findDaKing(int(chessTextFile[line][1]),int(chessTextFile[line][3]),0),"moves for the knight at",chessTextFile[line],"to capture the king at",chessTextFile[0]+"."
I hope the comments help. Sorry if its a little messy or hard to read.
Ps. thank you for all the responses this is my first time asking a question.
Here is my attempt but this isn't well optimized:
king = [4,1]
knight = [[6,3]]
c = 0
while king not in knight:
moves = []
for i in range(len(knight)):
for j in [-1,1]:
for k in [-2,2]:
for l in [0,1]:
if knight[i][l] + j>0 and knight[i][l] +j < 9 and knight[i][abs(l-1)] + k > 0 and knight[i][abs(l-1)] + k < 9:
moves.append([0,0])
moves[len(moves)-1][l] = knight[i][l] + j
moves[len(moves)-1][abs(l-1)] = knight[i][abs(l-1)] + k
c += 1
knight = list(moves)
print(c)