Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Skeleton file for BVP Practicum.
- #
- # You have to implement all of the functions in this file.
- #
- # If you implement them correctly, you can run this file to play the Slither game.
- # For that to work, this file has to be in the same directory as
- # the `slitherlib.py` file we provided.
- from slitherlib import Direction, Slither
- def create_new_world(game_size_x, game_size_y):
- """
- Creates a new world with dimensions game_size_x by game_size_y.
- The player's snake has length one (no body, just a head) and is positioned in the middle of the world.
- In case of an even game dimension, you may choose whether to round up or down.
- The player's snake starts out facing down.
- The world also includes food and other snakes at random locations.
- The value of the food is a random natural number between 1 and 9 (including 1 and 9).
- Every (empty) location then has a 1% probability of containing an enemy snake head.
- Every (still empty) location has a 2.5% probability of containing food.
- Note that the world description as you create it here will be passed on to the other functions that you will
- implement, such as game_to_string and forward. It should contain all the information that you need to implement
- these functions; you are free to choose your own representation.
- You may *optionally* give enemy snakes a body in addition to a head.
- If you want do to this, you can do so as follows:
- 75% of enemy snakes are of length 2 or higher, (75%)^2 of snakes are of length 3 or higher and so on.
- (so with 75% probability, you increase the length of the Snake by one and try increasing again)
- With every move they made, enemy snakes moved forward with a probability of 75%.
- When enemy snakes turn, they do so with equal probability in either direction.
- (so never to the direction opposite to their current one).
- Enemy snakes may overlap.
- :param game_size_x: Horizontal size of the game world.
- :param game_size_y: Verical size of the game world.
- :returns A data structure that holds all information about a new world.
- """
- world={}
- grid=[]
- length=0
- MaxScore=0
- food=[1,2,3,4,5,6,7,8,9]
- direction=Direction.DOWN
- for i in range (game_size_y):
- grid.append([])
- for j in range (game_size_x):
- grid[i].append(".")
- for i in range (game_size_y):
- for j in range (game_size_x):
- if grid[i][j]==".":
- p=randint(0,99)
- if p==7:
- grid[i][j]="X"
- else:
- g=randint(0,39)
- if g==6:
- r=randint(1,9)
- grid[i][j]=r
- MaxScore+=r
- world["grid"]=grid
- world["length"]=length
- world["location"]=(game_size_x//2, game_size_y//2)
- world["direction"]=direction
- world["MaxScore"]=MaxScore
- world["food"]=food
- return world
- def game_to_string(world):
- """
- Returns a string representation of the given world description.
- Use the following characters to represent game elements:
- * A "·" character for empty space
- * A number for a piece of food, where the number corresponds to the value of the food (1, 2, ... or 9).
- * A "X" character for a piece of enemy snake
- * A "O" character for the player's snake's head
- * A "o" character for a piece of the player's snake's body
- Example output:
- ························X··o··
- ························Oooo··
- ························X··o··
- ························X··o··
- ························X··o··
- ······················9·X··o··
- ························X··o3·
- :param world: Data structure holding information about the world as returned by create_new_world.
- :returns A multi-line string representing the given world description.
- """
- string=""
- for i in range (len(world["grid"])):
- for j in range(len(world["grid"][i])):
- if world["grid"][i][j]==".":
- string+="."
- elif world["grid"][i][j]=="X":
- string+="X"
- elif world["grid"][i][j] in world["food"]:
- string+=world["grid"][i][j]
- elif world["grid"][i][j]=="body":
- string+="o"
- elif world["grid"][i][j]=="head":
- string+="O"
- string+="\n"
- return string
- def forward(world):
- """
- If the game is over, this function does nothing.
- If the game is ongoing, this function modifies the given world description by moving the player's snake one step
- along its current direction.
- When moving over a piece of food, we say the snake eats the food.
- When eating a piece of food of value X, the player's snake should increase in length by X.
- The player's score should also increase by X.
- A snake's length is increased by moving its head while leaving the tail in place. It therefore takes
- some turns for food to be "processed". Snakes can eat more food while still processing old food.
- :param world: Data structure holding information about the world as returned by create_new_world.
- """
- if not is_game_over(world):
- if world["direction"]==Direction.Down:
- world["location"][1]-=1
- elif world["direction"]==Direction.Up:
- world["location"][1]+=1
- elif world["direction"]==Direction.Left:
- world["location"][2]-=1
- elif world["direction"]==Direction.Right:
- world["location"][2]+=1
- if world["grid"]["location"[1]]["location"[2]] in world["food"]:
- world["length"]+=world["grid"]["location"[1]]["location"[2]]
- for i in range(world["length"]):
- world["grid"]["location"[1]]["location"[2]]="body"
- forward(world)
- return world
- def turn_and_forward(world, direction):
- """
- If the game is over, this function does nothing.
- If the game is ongoing, this function modifies the given world description by moving the player's snake one step
- along the given direction. It also changes the player's snake's current direction to the given direction.
- If the given direction points "into" the snake, ignore the given direction and just move the players' snake along
- its current direction. Do not change the direction of the snake.
- For other things that happen when moving forward, see the documentation of the function forward.
- :param world: Data structure holding information about the world as returned by create_new_world.
- :param direction: Direction the player's snake should turn towards.
- direction is equal to either Direction.UP, Direction.RIGHT, Direction.DOWN or Direction.LEFT.
- """
- if not game_to_string(world):
- if direction==Direction.DOWN and world["direction"]!=Direction.UP:
- world["location"][1]-=1
- elif direction==Direction.UP and world["direction"]!=Direction.DOWN:
- world["location"][1]+=1
- elif direction==Direction.LEFT and world["direction"]!=Direction.RIGHT:
- world["location"][2]-=1
- elif direction==Direction.RIGHT and world["direction"]!=Direction.LEFT:
- world["location"][2]+=1
- else:
- forward(world)
- world["direction"]=direction
- return world
- def is_game_over(world):
- """
- Returns true iff this game is over and false iff the game is ongoing.
- The game is over when the snake has bumped into a square that contains another snake or when all the food is gone.
- Note that snakes are allowed to move "through" themselves; doing so does not end the game!
- :param world: Data structure holding information about the world as returned by create_new_world.
- """
- is_game_over=False
- if world["grid"]["location"[1]]["location"[2]]=="X" or world["length"]==world["MaxScore"]:
- is_game_over=True
- return is_game_over
- def get_score(world):
- """
- Returns the player's score in the given world.
- In a new world, player's scores are equal to zero. They are increased when eating food as described in forward.
- :param world: Data structure holding information about the world as returned by create_new_world.
- :return: The player's score as an integer.
- """
- return world["length"]
- # We put our "main" function here.
- if __name__ == "__main__":
- slither = Slither(create_new_world, game_to_string, forward, turn_and_forward, is_game_over, get_score)
- # Optionally set the speed at which the snake moves (expressed in milliseconds between ticks)
- # slither.set_waiting_time(1000)
- # We then start the GUI and start moving the snake; start will call back on your functions.
- slither.start(30, 10)
- # Functionally, the start function behaves as follows:
- #
- # def start(game_size_x, game_size_y):
- # world = create_new_world(game_size_x, game_size_y)
- # new_direction = None
- # print("Score: %i" % get_score(world))
- # print(game_to_string(world))
- # time.sleep(waiting_time/1000)
- # while not is_game_over(world):
- # if new_direction:
- # turn_and_forward(world, new_direction)
- # new_direction = None
- # else:
- # forward(world)
- # print("Score: %i" % get_score(world))
- # print(game_to_string(world))
- # time.sleep(waiting_time/1000)
- # print("Game over :(")
- # print("Final score: %i" % get_score(world))
- # print(game_to_string(world))
- #
- # new_direction is set whenever the user presses an arrow key, to the direction corresponding to the key press.
- # waiting_time is controlled by set_waiting_time as shown above; it has a default value of 500.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement