tictactoe iteration issue. Function error - function

I am new to programming (About 2 months in to teaching myself). I am attempting to create a game of tic tac toe and use it as an opportunity to practice using functions and passing parameters.
I have got most of what I want to work working (for now I will add AI and a computer opponent) but when one of the human players win the endgame() function is called but it does not work as expected. It calls itself somehow and you have got to say N to end the game three times before the program is terminated. I am unable to see the wood for the trees on this one folks so help would be appreciated.
I know some of my coding will not be great so no trolling please.
Thanks
Shaun
def start():
choices = [" "," "," "," "," "," "," "," "," "]
while checkwin(choices)==False:
board(choices)
getchoice(choices)
def board(choices):
print("+---+---+---+")
print("+ "+choices[0]+" + "+choices[1]+" + "+choices[2]+" +")
print("+---+---+---+")
print("+ "+choices[3]+" + "+choices[4]+" + "+choices[5]+" +")
print("+---+---+---+")
print("+ "+choices[6]+" + "+choices[7]+" + "+choices[8]+" +")
print("+---+---+---+")
def endgame(winner):
print("The winner is "+ winner)
playagain=input("Another game? Y/N")
playagain = playagain.upper()
if playagain == "N":
print("Thanks, hope to see you again soon.")
else:
start()
def getchoice(choices):
userchoice = int(input ("Where would you like to put your X?"))
index = userchoice-1
while choices[index]!=" ":
userchoice = int(input ("That space is taken. Where would you like to put your X?"))
index = userchoice-1
choices[index]="X"
board(choices)
if checkwin(choices)==False:
userchoice = int(input ("Where would you like to put your O?"))
index = userchoice-1
while choices[index]!=" ":
userchoice = int(input ("That space is taken. Where would you like to put your O?"))
index = userchoice-1
choices[index]="O"
checkwin(choices)
return choices
def checkwin (c):
if checkwin1(c)==False:
if checkwin2 (c)==False:
return False
else:
endgame("Player 2")
else:
endgame("Player 1")
def checkwin1(c):
return ((c[0]=="X" and c[1]=="X" and c[2]=="X") or
(c[3]=="X"and c[4]=="X" and c[5] =="X") or
(c[6]=="X"and c[7]=="X" and c[8] =="X") or
(c[0]=="X"and c[3]=="X" and c[6] =="X" )or
(c[1]=="X"and c[4]=="X" and c[7] =="X") or
(c[2]=="X"and c[5]=="X" and c[8] =="X") or
(c[0]=="X"and c[4]=="X" and c[8] =="X") or
(c[6]=="X"and c[4]=="X" and c[2] =="X"))
def checkwin2(c):
return ((c[0]=="O" and c[1]=="O" and c[2]=="O") or
(c[3]=="O"and c[4]=="O" and c[5] =="O") or
(c[6]=="O"and c[7]=="O" and c[8] =="O") or
(c[0]=="O"and c[3]=="O" and c[6] =="O" )or
(c[1]=="O"and c[4]=="O" and c[7] =="O") or
(c[2]=="O"and c[5]=="O" and c[8] =="O") or
(c[0]=="O"and c[4]=="O" and c[8] =="O") or
(c[6]=="O"and c[4]=="O" and c[2] =="O"))
start()

Let's imagine that X wins (because this is probably what caused it to "end") three times.
You then get to if checkwin(choices)==False: within getchoice(),
'checkwin()' happily calls endgame(). endgame() returns, and then getchoice() continues executing.
At the end of getchoice(), checkwin() is called again, with the same result.
After getchoice() returns we get back to while checkwin(choices)==False: within start(), once again with the same result.
Also note that you will see this happening even more times if you actually played multiple games in a row.
Also try making O win, I think you will only have to say no to your prompt twice in that case.
EDIT:
class TicTacToeGame:
INCOMPLETE = 0
WINNER_PLAYER_1 = 1
WINNER_PLAYER_2 = 2
DRAW = 3
SYMBOLS=["X","O"," "]
def __init__(self,player_1, player_2):
self.board = [[-1]*3,[-1]*3,[-1]*3]
self.players = [player_1,player_2]
self.current_turn = 0;
def advance(self):
if self.calcGameState() != TicTacToeGame.INCOMPLETE:
return
while True:
x,y = self.players[self.current_turn].getMove();
if x < 0 or x > 2 or y < 0 or y>2 :
continue
if self.board[y][x] == -1:
break
self.board[y][x] = self.current_turn
self.current_turn += 1
self.current_turn %= 2
def stringify(self):
re = ""
fr = True
for row in self.board:
if fr:
fr=False
else:
re+= "\n" + "---+" * 2 + "---\n"
fe = True
for el in row :
if fe:
fe = False;
else:
re += "|"
re += " " + TicTacToeGame.SYMBOLS[el] + " "
return re
def calcGameState(self):
for i in range(0,3):
#col
if all(self.board[i][j] == self.board[i][0] for j in range(0,3)) and self.board[i][0] != -1:
return self.board[i][0] + 1
#row
if all(self.board[j][i] == self.board[0][i] for j in range(0,3)) and self.board[0][i] != -1:
return self.board[0][i] + 1
if all(self.board[i][i] == self.board[0][0] for i in range(0,3)) and self.board[0][0] != -1:
return self.board[0][0] + 1
if all(self.board[i][2-i] == self.board[0][2] for i in range(0,3)) and self.board[0][2] != -1:
return self.board[0][2] + 1
if all(self.board[i][j] != -1 for i in range(0,3) for j in range(0,3)):
return TicTacToeGame.DRAW
return TicTacToeGame.INCOMPLETE
def stringResult(self):
res = self.calcGameState()
if res == TicTacToeGame.INCOMPLETE:
return "Incomplete"
if res == TicTacToeGame.DRAW:
return "Draw"
return "Player " + self.SYMBOLS[res-1] + " Won!"
class HumanPlayer:
def __init__(self):
self.board = None
def setGame(self,game):
self.game = game
def getMove(self):
print(self.game.stringify())
print("Current turn is: " + self.game.SYMBOLS[self.game.current_turn])
print("enter row for move")
y = input()
print("enter col for move")
x = input()
return int(x)-1,int(y)-1
def playAgain():
playagain=input("Another game? Y/N\n > ")
playagain = playagain.upper()
if playagain == "N":
print("Thanks, hope to see you again soon.")
return False
return True
while True:
p = HumanPlayer()
t = TicTacToeGame(p,p)
p.setGame(t)
while t.calcGameState() == TicTacToeGame.INCOMPLETE:
t.advance()
print(t.stringResult())
if not playAgain():
break;

Related

how to delete the same number of photos in mein dataset in python

Hi i use python and made a Dataframe of Food, which has 1000 photos for each food.
i wanna drop some pictures of food ex)ice_cream 100 pictures, omelette 100pictures... etc)
def get_df_from_file(path, is_valid):
img_df = pd.read_csv(path, delimiter='/', header=None, names=['label', 'name'])
# Append .jpg extension to all file names
img_df['name'] = img_df['label'].astype(str) + '/' + img_df['name'].astype(str) + '.jpg'
# Join extracted values and set is_valid
img_df['is_valid'] = is_valid
#img_df=img_df.loc[(img_df['label'] == 'ramen')]
return img_df
# Load the train set
train_df = get_df_from_file(path/'train.txt', False)
print(train_df.shape)
# Load the validation set
test_df = get_df_from_file(path/'test.txt', True)
print(test_df.shape)
# Concatenate train and test sets
image_df = pd.concat([train_df, test_df])
display(image_df.sample(10))
print(image_df.shape)
train_df0=train_df.loc[(train_df['label'] == df.label[0])]
drop_indices = np.random.choice(train_df0.index,50, replace=False)
train_df0 = train_df0.drop(drop_indices)
train_df1=train_df.loc[(train_df['label'] == df.label[1])]
drop_indices = np.random.choice(train_df1.index,50, replace=False)
train_df1 = train_df1.drop(drop_indices)
train_df2=train_df.loc[(train_df['label'] == df.label[2])]
drop_indices = np.random.choice(train_df2.index,50, replace=False)
train_df2 = train_df2.drop(drop_indices)
train_df3=train_df.loc[(train_df['label'] == df.label[3])]
drop_indices = np.random.choice(train_df3.index,50, replace=False)
train_df3 = train_df3.drop(drop_indices)
train_df4=train_df.loc[(train_df['label'] == df.label[4])]
drop_indices = np.random.choice(train_df4.index,50, replace=False)
train_df4 = train_df4.drop(drop_indices)
train_df5=train_df.loc[(train_df['label'] == df.label[5])]
drop_indices = np.random.choice(train_df5.index,50, replace=False)
train_df5 = train_df5.drop(drop_indices)
so 100 pictures each of 101category must be erased
i try to drop pictures of each dataframe but wenn i do this i should repeat this 100 times... how can i solve this problem with short syntax?

function with loop to include significance code

I would like to create a function that uses the input matrix and puts significance codes (*; ; *) besides the values in the matrix.
significance<-function(x){
for (i in 1:ncol(x)) {
for (j in 1:nrow(x)) {
paste(round(x[j,i], digits=4)
if (x[j,i]>2.58) {"***"}
else if (x[j,i]>1.96 {"**"}
else if (x[j,i]>1.645 {"*"} {""}, sep = "")
else if (x[j,i]>1.96) {"**"}
else if (x[j,i]>1.645) {"*"}
else if (x[j,i]<1.645) {""}, sep = "")
}}}

Invalid syntax for no reason

I cannot figure out why I keep receiving invalid syntax. Here is the function I can't figure out:
def coordType():
coordType = input("Automatic [a] or manual [m] message box coordinates?"
if coordType.lower not in ("a", "m"):
print("It must be 'a' or 'm'")
coordType()
elif coordType.lower() == "a":
print("Please put your mouse over the message box")
time.sleep(5)
xc, yc = m.position()
print("Done - " + str(xc) + ", " + str(yc))
elif coordType.lower() == "m":
xcoord()
ycoord()
try to indent everything.
the body of "coordType" is in the same allignment with the title, so it's invalid in python.

When calling different functions in the same class, only the first function is ever called(Python) [duplicate]

This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 6 years ago.
I'm having a bit of trouble with my class functions. On my class I have 3 different functions but whenever I call one of the functions outside of the class, it only ever calls the first one despite me typing in the correct function name.
This is the class below with the different functions, although I have only included two as I don't want you to have to search through lots of code.
class mage(baseclass):
def __init__(self, name, level, attack, defence, hp):
baseclass.__init__(self, name, level, hp)
self.attack = attack
self.defence = defence
def __str__(self):
return "You are now a Mage, your new stats are:\n Level: {0}\n Attack: {1}\n Defence: {2}\n HP: {3}".format(self.level, self.attack, self.defence, self.hp)
def flamevortex(self, x, y, z):
print("You used Flame Vortex")
time.sleep(1.5)
damageofmove = 3
damagedone = damageofmove*y
damagedoneafterdefence = damagedone - z
x = x - damagedoneafterdefence
print("The monster's health is now " + str(x))
time.sleep(1.5)
return x
def lightningbolt(self, x, y, z):
print("You used Lightning Bolt")
time.sleep(1.5)
damageofmove = 3
damagedone = damageofmove*y
damagedoneafterdefence = damagedone - z
x = x - damagedoneafterdefence
print("The monster's health is now " + str(x))
time.sleep(1.5)
return x
This is the place where I am calling the functions:
if Userattack.upper() == "FLAMEVORTEX" or "FLAME VORTEX":
monster1.hp = p1.flamevortex(monster1.hp, p1.attack, monster1.defence)
if chosenmove == monsterattacks[0]:
p1.hp = monsterlasersword(p1.hp)
elif chosenmove == monsterattacks[1]:
p1.hp = monsterswipe(p1.hp)
elif chosenmove == monsterattacks[2]:
monster1.hp = monsterregen(monster1.hp)
time.sleep(1.5)
print("After the monster's attacks, your hp is now " + str(p1.hp))
elif Userattack.upper() == "LIGHTNINGBOLT" or "LIGHTNING BOLT":
monster1.hp = p1.lightningbolt(monster1.hp, p1.attack, monster1.defence)
if chosenmove == monsterattacks[0]:
p1.hp = monsterlasersword(p1.hp)
elif chosenmove == monsterattacks[1]:
p1.hp = monsterswipe(p1.hp)
elif chosenmove == monsterattacks[2]:
monster1.hp = monsterregen(monster1.hp)
time.sleep(1.5)
print("After the monster's attacks, your hp is now " + str(p1.hp))
No matter what the user inputs, it only ever calls the first function.
I know this is a lot to process and appreciate any help. Thanks
if Userattack.upper() == "FLAMEVORTEX" or "FLAME VORTEX": means is userattack.upper() equal to "FLAMEVORTEX", or does the string "FLAME VORTEX" have True value.
Now since empty strings are False and non-empty strings are True, Userattack.upper() == "FLAMEVORTEX" or "FLAME VORTEX" is always True, and that's not what you meant.
Try: Userattack.upper() == "FLAMEVORTEX" or Userattack.upper()=="FLAME VORTEX"

Lua - Error repeating a function?

I'm working on an 'impossible' game, where you are basically asked a bunch of trick questions.
The first time I run the script, everything works perfectly. If the user decides to play again by typing in 'y', it will re-run the mainScript function. However, the script automatically re-runs the mainScript after finishing it a second time, without taking user input. I might be making a simple mistake, I'm not sure. Here is the script: (Sorry, I know it is kind of long)
math.randomseed(os.time())
local lives = 3
local points = 0
Questions = {
{"What is the magic word?", "A) Please", "B) Abra-Cadabra", "C) Lotion", "D) Cheese", "c"},
{"Does anyone love you?", "A) Yes", "B) No", "C) Everyone loves me!", "D) My mother does", "b"},
{"How many fingers do you have?", "A) None", "B) Eight", "C) Seventeen", "D) Ten", "d"},
{"What is 1 + 1?", "A) Window", "B) Door", "C) Two", "D) That's a stupid question", "a"}
}
savedQuestions = {} --Load the Questions table into savedQuestions
for i, v in pairs(Questions) do
table.insert(savedQuestions, v)
end
function loadTable() --Load the savedQuestions into Questions
for i = 1, #savedQuestions do
table.insert(Questions, savedQuestions[i])
end
end
function waitForStart()
local chk = io.read() tostring(chk)
if (chk:sub(1, 5)):lower() == "start" then
return true
end
waitForStart()
end
function lookForAnswer(ans)
table.remove(Questions, number)
local input = io.read() tostring(input)
if input:lower() == ans then
points = points + 1
return true
end
lives = lives - 1
return false
end
function mainScript()
lives = 3
points = 0
print("Welcome to the Impossible quiz!")
print("Type 'start' when you are ready to begin\n")
waitForStart() io.write("\n")
for i = 1, #Questions do
number = math.random(1, #Questions)
local prob = Questions[number]
local q = prob[1]
local a = prob[6]
print(q)
print(prob[2] .. "\n" .. prob[3] .. "\n" .. prob[4] .. "\n" .. prob[5] .. "\n")
if lookForAnswer(a) then
print("Correct! Points: " .. points .. " Lives: " .. lives .. "\n\n")
else
print("WRONG! Points: " .. points .. " Lives: " .. lives .. "\n\n")
if lives <= 0 then
return false
end
end
end
return true
end
function checkForReplay()
print("Would you like to play again? (Y / N)")
local chk = io.read() tostring(chk)
if (chk:sub(1, 1)):lower() == "y" then
return true
end
return false
end
function checkWin()
if mainScript() then
print("You won!")
print("Points: " .. points .. "\n")
if checkForReplay() then
Questions = {}
loadTable()
mainScript()
else
exit()
end
else
print("You lose!")
print("Points: " .. points .. "\n")
if checkForReplay() then
Questions = {}
loadTable()
mainScript()
else
exit()
end
end
end
while true do
checkWin()
end
You should factor out the "startover" logic into the loop, you would see better. Then you notice how there is common code in both if chunks of your checkWin, factor that out too:
function checkWin()
if mainScript() then
print("You won!")
else
print("You lose!")
end
print("Points: " .. points .. "\n")
if not checkForReplay() then
exit()
end
end
while true do
checkWin()
-- if you get here you have not exited so start over:
Questions = {}
loadTable()
mainScript() -- oops! what's that doing here?
end
Note also that it is better to let the script return than call os.exit() (assuming that is what exit() is in your code -- see for example How to terminate Lua script?):
function checkWin()
if mainScript() then
print("You won!")
else
print("You lose!")
end
print("Points: " .. points .. "\n")
return checkForReplay()
end
local playAgain = checkWin()
while playAgain do
Questions = {}
loadTable()
playAgain = checkWin()
end