This task is to determine the difference between two attributes, strength and skill, from game characters. The process for this is:
Determining the difference between the strength attributes.
The difference is divided by five and rounded down to create a ‘strength modifier’.
The same process is carried out for the skill attribute and named ‘skill modifier’.
Then the game begins:
Both players throw a six sided die.
If the values are the same, no changes happen.
If the values are different, the player with the highest value then gains the strength and skill worked out earlier and it is then added to their total. The player who has the lowest value has the strength and skill worked out taken away from their total.
This must repeat until the strength attribute is equal or below 0, however, this part I cant do, I know how to loop but this is always done by asking the user if they wish to go again.
c1sc=random.randint(1,6)
c2sc=random.randint(1,6)
if c1sc > c2sc:
c1st=c1st+strengthmodifier
c2st=c2st-strengthmodifier
c1sk=c1sk+skillmodifier
c2sk=c2sk-skillmodifier
print('Character 1, your strength attribute is: '+(str(c1st))+' and your skill attribute is: '+(str(c1sk)))
print('Character 2, your strength attribute is: '+(str(c2st))+' and your skill attribute is: '+(str(c2sk)))
elif c2sc > c1sc:
c1st=c1st-strengthmodifier
c2st=c2st+strengthmodifier
c1sk=c1sk-skillmodifier
c2sk=c2sk+skillmodifier
print('Character 1, your strength attribute is: '+(str(c1st))+' and your skill attribute is: '+(str(c1sk)))
print('Character 2, your strength attribute is: '+(str(c2st))+' and your skill attribute is: '+(str(c2sk)))
else:
print('It\'s a draw, no changes were made.')
if c1sk < 0:
c1sk=0
elif c2sk < 0:
c2sk=0
if c1st < 0:
print('Character 1 died. Game over.')
elif c2st < 0:
print('Character 2 died. Game over.')
Please help!
Let me introduce you to the while loop. You use this when you want something to occur if the specified condition is true or false.
I briefly edited your code.
import random
def main():
player1=20
player2=12
strength=(20-10)/5
strength_mod=int(strength)
while player1>0 and player2>0:
dice1=random.randint(1,6)
dice2=random.randint(1,6)
if dice1>dice2:
player1+=strength_mod
player2-=strength_mod
print("Player 1 strength is: ", player1)
print("Player 2 strength is: ", player2)
elif dice1<dice2:
player2+=strength_mod
player1-=strength_mod
print("Player 1 strength is: ", player1)
print("Player 2 strength is: ", player2)
main()
I gave players 1 and 2 initial values bet these can be changed to your liking. To round down, I made another variable and changed strength to an integer.
Just so you get the picture: (in pseudocode)
while (c2sk > 0 && c1sk > 0)
//do complete everything up until the if statements
if c1st <0
print "c1st died"
elif c2st <0
print "c2st died"
Not sure if this is what you are looking for exactly. If the c2sk and c1sk is supposed to be randomly reassigned each time it should be inside the loop.
Add another loop to do the reductions...
c1sc=random.randint(1,6)
c2sc=random.randint(1,6)
if c1sc > c2sc:
while c2st > 0 and c2sk > 0:
c1st=c1st+strengthmodifier
c2st=c2st-strengthmodifier
c1sk=c1sk+skillmodifier
c2sk=c2sk-skillmodifier
print('Character 1, your strength attribute is: '+(str(c1st))+' and your skill attribute is: '+(str(c1sk)))
print('Character 2, your strength attribute is: '+(str(c2st))+' and your skill attribute is: '+(str(c2sk)))
elif c2sc > c1sc:
while c1st > 0 and c1sk > 0:
c1st=c1st-strengthmodifier
c2st=c2st+strengthmodifier
c1sk=c1sk-skillmodifier
c2sk=c2sk+skillmodifier
print('Character 1, your strength attribute is: '+(str(c1st))+' and your skill attribute is: '+(str(c1sk)))
print('Character 2, your strength attribute is: '+(str(c2st))+' and your skill attribute is: '+(str(c2sk)))
else:
print('It\'s a draw, no changes were made.')
if c1sk < 0:
c1sk=0
elif c2sk < 0:
c2sk=0
if c1st < 0:
print('Character 1 died. Game over.')
elif c2st < 0:
print('Character 2 died. Game over.')
Of course, there are much more compact ways of writing this. This still isn't ideal but is a reduction in code...
c1sc=random.randint(1,6)
c2sc=random.randint(1,6)
if c1sc != c2sc:
while c1st > 0 and and c2st > 0:
c1st += strengthmodifier if c1sc > c2sc else -1 * strengthmodifier
c2st += strengthmodifier if c1sc < c2sc else -1 * strengthmodifier
c1sk += skillmodifier if c1sc > c2sc else -1 * skillmodifier
c2sk += skillmodifier if c1sc < c2sc else -1 * skillmodifier
print('Character 1, your strength attribute is: '+(str(c1st))+' and your skill attribute is: '+(str(c1sk)))
print('Character 2, your strength attribute is: '+(str(c2st))+' and your skill attribute is: '+(str(c2sk)))
c1sk = math.max(c1sk, 0) # Clamp skill to a minimum of 0
c2sk = math.max(c2sk, 0) # ...
if c1st < c2st:
print('Character 1 died. Game over.')
else:
print('Character 2 died. Game over.')
else:
print('It\'s a draw, no changes were made.')
And finally, assuming a re-roll every round...
while c1st > 0 and and c2st > 0:
c1sc=random.randint(1,6)
c2sc=random.randint(1,6)
if c1sc != c2sc:
c1st += strengthmodifier if c1sc > c2sc else -1 * strengthmodifier
c2st += strengthmodifier if c1sc < c2sc else -1 * strengthmodifier
c1sk += skillmodifier if c1sc > c2sc else -1 * skillmodifier
c2sk += skillmodifier if c1sc < c2sc else -1 * skillmodifier
print('Character 1, your strength attribute is: '+(str(c1st))+' and your skill attribute is: '+(str(c1sk)))
print('Character 2, your strength attribute is: '+(str(c2st))+' and your skill attribute is: '+(str(c2sk)))
else:
print('It\'s a draw, no changes were made.')
c1sk = math.max(c1sk, 0) # Clamp skill to a minimum of 0
c2sk = math.max(c2sk, 0) # ...
if c1st < c2st:
print('Character 1 died. Game over.')
else:
print('Character 2 died. Game over.')
Related
im new in Python and i'm self learner. Actually im trying to create easy word game.
Currently im in stage when im adding monster/player damage and I have three problems which i can't figure out.
I want every room to have a chance for a random monster to appear from "Monster" dictionary. However, after meeting a monster for the first time, the value of his life after the fight is overwritten in the dictionary. This causes the monster to have a negative life when you meet it again. How to fix it?
When i'll find monster in any room, I have set two options "run" and "fight". When someone will type any other command, the loop returns to the draw whether a monster or a chest will appear in the room. I want the return to occur until after the event is randomly selected
I have problem with placing command
if playerLife <= 0:
print("You died, your body will lay in chambers forever")
break
I want to end game immidiatly after players dead.
import random
from enum import Enum
playerDamage = 4
playerLife = 100
def find_aprox_value(value):
lowestValue = 0.9 * value
highestValue = 1.1 * value
return random.randint(lowestValue, highestValue)
def weapon_hit(chance):
if_hit = random.uniform(1, 100)
if if_hit < chance:
monsterLife[drawnMonster] = monsterLife[drawnMonster] - playerDamage
print("You hit a monster and you dealt 4 damage. It has", monsterLife[drawnMonster], " life")
else:
print("You missed")
def monster_hit():
global playerLife
monsterHit = monsterDamage[drawnMonster]
print("Monster did", monsterDamage[drawnMonster], "damage")
playerLife = playerLife - monsterHit
print("You have ", playerLife, "life")
Event = Enum('Event', ['Chest', 'Monster'])
Chest = Enum('Chest', {'greenChest': 'zieloną skrzynię',
'blueChest': 'niebieską skrzynię',
'violetChest': 'fioletową skrzynię',
'orangeChest': 'pomarańczową skrzynię'
})
Monster = Enum('Monster', {'Rat': 'Szczura',
'Bat': 'Nietoperza',
'GiantSpider': 'Ogromnego Pająka',
'Wolf': 'Wilka',
})
Color = Enum('Color', ['greenChest', 'blueChest', 'violetChest', 'orangeChest'])
MonsterKind = Enum('MonsterKind', ['Rat', 'Bat', 'GiantSpider', 'Wolf'])
eventDictionary = {
Event.Chest: 0.4,
Event.Monster: 0.6
}
eventList = list(eventDictionary.keys())
eventProbability = list(eventDictionary.values())
chestDictionary = {
Chest.greenChest: 0.5,
Chest.blueChest: 0.3,
Chest.violetChest: 0.15,
Chest.orangeChest: 0.05
}
PremiumChestDictionary = {
Chest.blueChest: 0.5,
Chest.violetChest: 0.35,
Chest.orangeChest: 0.15
}
MonsterDictionary = {
Monster.Rat: 0.5,
Monster.Bat: 0.3,
Monster.GiantSpider: 0.15,
Monster.Wolf: 0.05
}
chestList = list(chestDictionary.keys())
chestProbability = list(chestDictionary.values())
MonsterList = list(MonsterDictionary.keys())
MonsterProbability = list(MonsterDictionary.values())
PremiumChestList = list(PremiumChestDictionary.keys())
PremiumChestProbability = list(PremiumChestDictionary.values())
colorValue = {
Chest.greenChest: 1000,
Chest.blueChest: 4000,
Chest.violetChest: 9000,
Chest.orangeChest: 16000
}
monsterLife = {
Monster.Rat: 5,
Monster.Bat: 10,
Monster.GiantSpider: 15,
Monster.Wolf: 30
}
monsterDamage = {
Monster.Rat: 3,
Monster.Bat: 5,
Monster.GiantSpider: 8,
Monster.Wolf: 12
}
gameLength = 10
Gold = 0
while gameLength > 0:
gameAnswer = input("Do you want to move forward? \n")
if gameAnswer == "yes":
print("Great, lets see what is inside")
drawnEvent = random.choices(eventList, eventProbability)[0]
if drawnEvent == Event.Chest:
drawnChest = random.choices(chestList, chestProbability)[0]
goldAcquire = find_aprox_value(colorValue[drawnChest])
print("You have find ", drawnChest.value, "inside was", goldAcquire, "gold")
Gold = Gold + goldAcquire
gameLength = gameLength - 1
elif drawnEvent == Event.Monster:
drawnMonster = random.choices(MonsterList, MonsterProbability)[0]
print("Oh no, you have find", drawnMonster.value, "which has", monsterLife[drawnMonster],
"life .If you will defeat him, you will find great treasure.")
eventAnswer = input(" What is your choice?(fight, run)")
if eventAnswer == "fight":
while monsterLife[drawnMonster] > 0:
weapon_hit(70)
if monsterLife[drawnMonster] > 0:
monster_hit()
if playerLife <= 0:
print("You died, your body will lay in chambers forever")
break
drawnPremiumChest = random.choices(PremiumChestList, PremiumChestProbability)[0]
goldAcquire = find_aprox_value(colorValue[drawnPremiumChest])
print("Congratulations, you have defeat a monster, and you found", drawnPremiumChest.value,
", inside was", goldAcquire, " gold")
Gold = Gold + goldAcquire
gameLength = gameLength - 1
elif eventAnswer == "run":
gameLength = gameLength - 1
print("you have successfully run")
else:
print("Only options is run or fight")
continue
else:
print("Your only options is move forward")
continue
print("Congratulations you have acquired", Gold, "gold")
As I mentioned at the beginning, I am just starting to learn python and this is my first post on this forum, so please be understanding and thank you for your help in advance.
There are many solutions to your problem (at least five). Here are the simplest:
The simplest: Instead of break, you can end the program with sys.exit (0) (with code 0 because it's not an error).
More elegant:
# Outer loop:
while gameLength > 0 and playerLife > 0:
# Inner loop:
while monsterLife[drawnMonster] > 0 and playerLife > 0:
# Statement 'if playerLife <= 0' becomes redundant
# Outside the loop:
if playerLife > 0:
print("Congratulations ...")
else:
print("You died, ...")
or:
# Outer loop:
while gameLength > 0 and playerLife > 0:
# Inner loop:
while monsterLife[drawnMonster] > 0:
if playerLife <= 0:
break
# Outside the loop:
if playerLife > 0:
print("Congratulations ...")
else:
print("You died, ...")
More advanced: instead of using break statement, an exception can be thrown. The exception must be handled by the try ... catch statement.
BTW: both continue statements are completely unnecessary - these are the last statements of the loop, so they don't change anything about the execution of the loop.
Have fun with Python.
I'm doing an interactive map and after reading on the Internet, I'm trying to develop my learn towards an efficient way of programming. I wonder, is there a way to write more efficient this kinds of if_elif tree's ? I've read that one way is to make every conditions a def and store the conditions in a tuple ( 'cause is more efficiente than a list, and the values won't change). I've considered using ternary operator but don't know if is gonna be more efficient.
if direction == "w":
point[POS_Y] -= 1
elif direction == "s":
point[POS_Y] += 1
elif direction == "a":
point[POS_X] -= 1
elif direction == "d":
point[POS_X] += 1
Here's the code:
POS_X = 0
POS_Y = 1
MAP_WIDTH = 20
MAP_HEIGHT = 15
point = [3,7]
while 1: # i've read that Python is more efficient using a 1 instead of a True
# def player_movement(point):
print('+' + '-' * MAP_WIDTH * 3 + '+')
for coordinate_y in range(MAP_HEIGHT):
print('|',end='')
for coordinate_x in range(MAP_WIDTH):
if point[POS_X] == coordinate_x and point[POS_Y] == coordinate_y:
print(' #',end='') # it works with ' # ' as well, but in Visual Code doesn't see though
else:
print(' ',end='')
print('|')
print('+' + '-' * MAP_WIDTH * 3 + '+')
# player_movement([3,8])
direction = readchar.readchar().decode()
if direction == "w":
point[POS_Y] -= 1
elif direction == "s":
point[POS_Y] += 1
elif direction == "a":
point[POS_X] -= 1
elif direction == "d":
point[POS_X] += 1
If you have python 3.10 and above you can use the switch statement.
Here is an example:
status = 404
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the internet"
This is called structural pattern matching and the link to the docs are here: https://docs.python.org/3.10/whatsnew/3.10.html#pep-634-structural-pattern-matching
As mentioned in the comments, this is no faster that if, elif statements from previous versions. So is important to mention.
After doing a quick test (python version 3.10.0) it seems that elif takes the most time, match comes second and using a dict is the fastest way.
test_elif
def test_elif():
direction = random.choice(['w','a','s','d'])
if direction == "w":
point[1] -= 1
elif direction == "s":
point[1] += 1
elif direction == "a":
point[0] -= 1
elif direction == "d":
point[0] += 1
return
test_match
def test_match():
direction = random.choice(['w','a','s','d'])
match direction:
case "w":
point[1] -= 1
case "s":
point[1] += 1
case "a":
point[0] -= 1
case "d":
point[0] += 1
return
test_dict
def test_dict():
direction = random.choice(['w','a','s','d'])
md = modifiers[direction]
point[md[0]] += md[1]
return
setup
import random
modifiers = {
"w": (1, -1),
"s": (1, +1),
"a": (0, -1),
"d": (0, +1)
}
point = [0,0]
Tested with timeit.timeit(funcntion_call, setup=setup, number=1000000)
test_elif: 0.1586214000126347 seconds
test_match: 0.1482315000030212 seconds
test_dict: 0.13923519995296374 seconds
When I execute the following code, I get the error "player_normal_defense is not defined". I get what the issue is but if I had to define the variable inside the Defense function, it would be totally pointless since the variable stores the initial defense value for further usage. How should I solve this?
import random
import sys
import os
import time
from Entity import *
class Battle():
def Attack(self, attacker, defender):
damage = attacker.atk - defender.dif
defender.hp -= damage
def Defense(self, owner, defending, entity_id):
defense_boost = 10
if defending:
owner.dif += defense_boost
elif not defending:
if entity_id == 1:
owner.dif = player_normal_defense
elif entity_id == 2:
owner.dif = enemy_normal_defense
def Turn_Generator(self, pl, en):
turns_list = []
speed_product = pl.speed / en.speed
first_speed_product = speed_product
if speed_product >= 1:
turns_list.append("P")
elif speed_product < 1:
turns_list.append("E")
while len(turns_list) < 100:
if speed_product >= 2:
turns_list.append("P")
turns_list.append("P")
speed_product = 0.6
elif speed_product < 2 and speed_product >= 1:
turns_list.append("P")
if first_speed_product <= 0.5:
speed_product = first_speed_product
else:
speed_product = 0.6
elif speed_product <= 0.5:
turns_list.append("E")
turns_list.append("E")
speed_product = 1
elif speed_product > 0.5 and speed_product < 1:
turns_list.append("E")
if first_speed_product >= 2:
speed_product = first_speed_product
else:
speed_product = 1
return turns_list
def Combat(self, player, enemy):
turn_counter = 1
player_normal_defense = player.dif
enemy_normal_defense = enemy.dif
fighting = True
while fighting:
print(f"Turn {turn_counter}")
turns = self.Turn_Generator(player, enemy)
for current_turn in turns:
print(f"""
======================
YOUR HPs: ENEMY HPs:
{player.hp} {enemy.hp}
======================""")
print(f"""
================
Current turn: {current_turn}
================
===========
Next turns:
{turns[1]}
{turns[2]}
{turns[3]}
{turns[4]}
===========
""")
if current_turn == "P":
choice = input("1. Attack\n2. Defend\n")
if choice == "1":
self.Attack(player, enemy)
self.Defense(player, False, 1)
elif choice == "2":
self.Defense(player, True, 1)
else:
print("Lost your chance!")
elif current_turn == "E":
enemy_choice = random.randint(1, 2)
if enemy_choice == 2:
print("He attacks you!")
self.Attack(enemy, player)
self.Defense(enemy, False, 2)
else:
print("He defends himself.")
self.Defense(enemy, True, 2)
time.sleep(3)
os.system("clear")
turns.pop(0)
if player.hp <= 0:
print("You died!")
sys.exit(0)
elif enemy.hp <= 0:
print("YOU WON!")
fighting = False
break
turn_counter += 1
When entity is defending, instead of running a Defence function to add a bonus to entitys Defence score only if it is true, I would just not run the Defence function when attacking. When entity is defending then you can run the Defense (Bonus) function as;
def Defending():
defence_boost = 10
in the decision check;
if choice == "2":
self.dif += Defending()
One issue I believe you will have with the code is that you are raising the entitys .dif stat with each occurrence of defending. This means that when this has cycled multiple times the base dif may be too high for any attackers damage to do anything to the opponents health.
I just started to learn python(self-taught) and I'm trying to do a simulation of racquetball game.
I can run the simulation with: a==15 or b==15, but when I add the extra condition: abs(a-b)>=2 IT GOES CRAZY(the simOneGame turns to an infinite loop). Here is what I tried so far:
return a == 15 or b == 15 ------> this one works perfectly
return a == 15 or b == 15 and abs(a-b) >= 2 --> this doesn't freeze but the logic is wrong(I think)
return (a == 15 or b == 15) and abs(a-b) >= 2 --> freezing
return (a == 15 or b == 15) and (abs(a-b) >= 2) --> freezing
return ((a == 15 or b == 15) and (abs(a-b) >= 2)) --> freezing
Thanks a lot and sorry if this seems too long(maybe I should've typed just the function gameOver()?...)
Here is my code so far:
from random import random
def main():
printIntro()
n, probA, probB = getInputs()
winsA, winsB = simNGames(n, probA, probB)
displayResults(winsA, winsB)
def printIntro():
print("\nVOLLEYBALL SIMULATION\n")
print("The inputs will be the number of simulations(n),")
print(" the probability player A wins his serve(probA)")
print(" and the probability player B wins his serve(probB).")
print("The program will display how many games won player A(winsA),")
print(" how many games won player B(winsB),")
print(" and the percentages of winnings for both players.\n")
def getInputs():
n = int(input("Enter the number of simulations: "))
probA = float(input("Enter the probability player A wins his serve: "))
probB = float(input("Enter the probability player B wins his serve: "))
return n, probA, probB
def simNGames(n, probA, probB):
winsA, winsB = 0, 0
for i in range(n):
# player A serves on odd games
if i % 2 == 0:
serving = "A"
# player B serves on even games
else:
serving = "B"
scoreA, scoreB = simOneGame(probA, probB, serving)
if scoreA > scoreB:
winsA = winsA + 1
else:
winsB = winsB + 1
return winsA, winsB
def simOneGame(probA, probB, serving):
scoreA, scoreB = 0, 0
while not gameOver(scoreA, scoreB):
if serving == "A":
if random() < probA:
scoreA = scoreA + 1
else:
serving = "B"
else:
if random() < probB:
scoreB = scoreB + 1
else:
serving = "A"
return scoreA, scoreB
def gameOver(a, b):
# the game is over if a player gets to 15 AND the difference is at least 2.
# this shoud work... BUT IT DOESN'T... simOneGame turns to an infinete loop with a large number of simulations...
return (a == 15 or b == 15) and abs(a-b) >= 2
def displayResults(winsA, winsB):
print("Player A won {0} games({1:1.0%})".format(winsA, winsA/(winsA+winsB)))
print("Player B won {0} games({1:0.0%})".format(winsB, winsB/(winsA+winsB)))
if __name__ == "__main__":
main()
I'm building out Battleships game in Python. I have a list and I'm trying to build a validation tool in Python to catch user inputs that are outside the 10x10 range of my list.
Here is the code:
from random import randint
player = "User"
board = []
board_size = 10
ships = {"Aircraft Carrier":5,
"Battleship":4,
"Submarine":3,
"Destroyer":3,
"Patrol Boat":2}
def print_board(player, board): # to print joined board
print("Here is " + player + "'s board")
for row in board:
print(" ".join(row))
def switch_user(player): # to switch users
if player == "User":
player = "Computer"
elif player == "Computer":
player = "User"
else:
print("Error with user switching")
for x in range(0, board_size): # to create a board
board.append(["O"] * board_size)
print_board(player,board)
def random_row(board): # generate random row
return randint(0, len(board) - 1)
def random_col(board): # generate random column
return randint(0, len(board[0]) - 1)
def user_places_ships(board, ships): # user choses to place its ships by providing starting co-ordinate and direction.
for ship in ships:
valid = False
while(not valid):
user_input_coordinates = input("Please enter row & column number for your " + str(ship) + ", which is " + str(ships[ship]) + "-cells long (row, column).")
ship_row, ship_col = user_input_coordinates.split(",")
ship_row = int(ship_row)
ship_col = int(ship_col)
user_input_dir = input("Please enter direction for your " + str(ship) + ", which is " + str(ships[ship]) + "-cells long (h for horizontal or v for vertical).")
valid = validate_coordinates(board, ships[ship], ship_row, ship_col, user_input_dir)
if not valid:
print("The ship coordinates either outside of" , board_size, "X" , board_size, "range, overlap with or too close to another ship.")
place_ship(board, ships[ship], ship_row, ship_col, user_input_dir)
print("You have finished placing all your ships.")
def validate_coordinates(board, ship_len, row, col, dir): # validates if the co-ordinates entered by a player are within the board and don't overlap with other ships
if dir == "h" or dir == "H":
for x in range(ship_len):
if row-1 > board_size or col-1+x > board_size:
return False
elif row-1 < 0 or col-1+x < 0:
return False
elif board[row-1][col-1+x] == "S":
return False
elif dir == "v" or dir == "V":
for x in range(ship_len):
if row-1+x > board_size or col-1 > board_size:
return False
elif row-1+x < 0 or col-1 < 0:
return False
elif board[row-1+x][col-1] == "S":
return False
return True
def place_ship(board, ship_len, row, col, dir): # to actually place ships and mark them as "S"
if dir == "h" or dir == "H":
for x in range(ship_len):
board[row-1][col-1+x] = "S"
elif dir == "v" or dir == "V":
for x in range(ship_len):
board[row-1+x][col-1] = "S"
else:
print("Error with direction.")
print_board(player,board)
user_places_ships(board,ships)
If a user enters "10,10" for ship coordinates and "h" for horizontal direction, then Python generates the following error message:
Traceback (most recent call last): File "C:/Users/Elchin's PC/Downloads/battleships game.py", line 85, in <module>
user_places_ships(board,ships) File "C:/Users/Elchin's PC/Downloads/battleships game.py", line 49, in user_places_ships
valid = validate_coordinates(board, ships[ship], ship_row, ship_col, user_input_dir) File "C:/Users/Elchin's PC/Downloads/battleships game.py", line 62, in validate_coordinates
elif board[row-1][col-1+x] == "S": IndexError: list index out of range
I know that the error is in this line:
elif board[row-1][col-1+x] == "S":
return False
But I don't know how to fix it. Could you please help me figure out the solution?
If a list has length n, you can access indices from 0 to n-1 (both inclusive).
Your if statements however check:
if row-1+x > board_size or col-1 > board_size: # greater than n
return False
elif row-1+x < 0 or col-1 < 0: # less than 0
return False
elif board[row-1+x][col-1] == "S":
return False
So as a result, if we reach the last elif part, we have guarantees that the indices are 0 < i <= n. But these should be 0 < i < n.
So you should change the first if statement to:
if row-1+x >= board_size or col-1 >= board_size: # greater than or equal n
return False
elif row-1+x < 0 or col-1 < 0: # less than 0
return False
elif board[row-1+x][col-1] == "S":
return False
You can make the code more elegant by writing:
if not (0 < row-1+x < board_size and 0 < col-1 < board_size) or \
board[row-1+x][col-1] == "S":
return False