I want to make sure the code below includes sequences - python

def reset_score(game):
time.sleep(0.5) # the snake freezes for a moment when hitting a wall then the game resets
head.goto(0, 0)
head.direction = "stop"
score = 0
# I could not find a way to remove the tails once the snake hit the wall
# so I moved the tail to somewhere in the screen that is not visible____This is called creativity
for game in snake_tail:
game.goto(1000, 1000)
score_printer.clear()
score_printer.write("Score: {} High Score: {}".format(score, high_score), align="center", font=("italic", 24, "normal"))
snake_tail.clear()
is "game.goto(1000,1000)" a tuple? or does this code include any other sequence. I am really not sure about a clear definition of sequence so I am not sure whether these are sequences or not?

Let's try to understand Sequence in brief, The main sequence types in Python are lists, tuples, and range objects. The main differences between these sequence objects are:
Lists are mutable and their elements are usually homogeneous (things of the same type making a list of similar objects)
Tuples are immutable and their elements are usually heterogeneous (things of different types making a tuple describing a single structure)
Range objects are efficient sequences of integers (commonly used for loops), use a small amount of memory, and yield items only when needed.
Also regarding game.goto(), goto() is used to move the turtle(pre-installed Python library that enables users to create pictures and shapes by providing them with a virtual canvas) at x and y coordinates.
I hope it is understandable now.

Related

How to optimize for loop - Python 3

My very first post, sorry if I made any mistakes!
I'm messing around the pygame library, and I'm extremely new to python in general. I have created 3 enemies classes and they work as intended, however, this is how I make them move (I call the move function stored inside the class).
I wonder if there is a more clean way to do things. I have many other enemies to code and this seems very repetitive to type, so it's a sign I'm doing something wrong.
I tried creating a "control list" where I list every enemy list there is and I try to access them through their index but it isn't working. I also tried to concatenate but I'm getting an error saying I can't concatenate list names, another error was that my list names turned into strings (yes, I tried using quotation marks). I'm sure this will be a simple fix, but I spent 3 days and I wrap my head around it. If it's possible to do so
The sample of my code so far - it is located in the main run loop of my game.
for giant in lst_enemy_giants:
giant.move()
else:
pass
for spider in lst_enemy_spiders:
spider.move()
else:
pass
for goblin in lst_enemy_goblin:
giant.move()
else:
pass
# The pattern the I want
for ENEMY in lst_enemy_ENEMY:
ENEMY.move()
# where ENEMY is any enemy list that can be stored somewhere
Just chain the iterators together.
from itertools import chain
for enemy in chain(lst_enemy_giants, lst_enemy_spiders, lst_enemy_goblin):
enemy.move()
This is a slightly nicer way of writing a nested loop like
for enemy_list in [lst_enemy_giants, lst_enemy_spiders, lst_enemy_goblin]:
for enemy in enemy_list:
enemy.move()
Unrelated, but I recommend keeping a single dict like
enemies = {'giants': [...], 'spiders': [...], 'goblins': [...]}
rather than three separate variables referencing separate lists. You can still use, for example, enemies['giants'] anywhere you would have used lst_enemy_giants, but now you can write
for enemy in chain(*enemies.values()):
enemy.move()

Python question about functions classes and class methods

I am fairly new to intermediate programming, yet have played around with code for a while.
At the moment I am making a simple card game.
This issue is I am not sure where to use my functions or when to make them class methods.
For example, here is a simple function that deals out 5 cards to each player (from a predefined list) and then turns a card from the top of the pack (actually all just random selections).
The cards are returned as a list of items (3 lists).
I have also made a class called "Player".
p1_hand = []
p2_hand = []
flip_card = []
def deal_deck():
count = 0
for i in range(0, 10, 1):
count += 1
if count % 2 == 0:
card = random.choice(deck)
p2_hand.append(card)
deck.remove(card)
else:
card = random.choice(deck)
p1_hand.append(card)
deck.remove(card)
if count == 10:
flip_card.append(random.choice(deck))
return p2_hand, p1_hand, flip_card
In this example, it's just a deal, so I wonder why it would need to be a class method of "Player"?
Possibly the class "Player" does not do much at all except keep score, keep track of who is dealing and what the score is?
To put it simply I am having trouble understanding the class as an object that interacts and preforms actions, I have made other classes and they have ended up working like a mini database rather than using much complexity in the methods at all.
There is an art to designing classes and objects. The fundamental purpose of using classes is information hiding. The rest of your program should not have to know how a deck of cards is implemented, which allows you to change the implementation without redesigning the whole program. Thus, you create a Deck class that has all of the data stored internally, and only exposes to the outside world the things you want to DO with a deck, like shuffle and deal_card. A Player class might include a hand and a score, and functions to add another card, and the Game object (maybe) could coordinate dealing cards into the hand and triggering the plays.
The code you have is mixing all of this. It has to know how a deck is implemented, and how a hand is implemented, and how a card is flipped.
By the way, for the sake of realism, it would be better for you to shuffle the deck and deal cards off the top, instead of using random.choice.
I originally down-voted this as too broad, but changed my mind as I wrote up my notes for you. Classes are a programming tool whose implementation doesn't receive much treatment at the level you're asking. There are many examples of good card-game classes available on the Internet ... and many bad ones. The research isn't easy for you.
Use a class to represent a unit of your system (a card game, in this case) that is cohesive (a set of data and capabilities with a readily understood boundary) and interacts with other units, or with the main program.
In this case, you have a good start: you've identified card, player, and hand as entities in your game system. You may want to treat the deck as a hand instance (just another list of cards), or you may want to give it special treatment due to different functions within the game.
The classes and functions I've seen as useful include:
Deck
The impartial source of cards
data
a list of cards
methods
reset -- shuffle all 52 cards into a list
deal(n) -- return a list of n cards
Hand
cards held by a single player
data
a list of cards
methods
reset -- whatever is needed to return the hand to a game-start state
draw(n) -- acquire n cards
play(n) -- play n cards to the game area
Card
A single card, containing all information needed to identify it to the game
data
suit
rank
methods
none
Player
Game information about each player
data
hand -- see Hand class above
game-role -- depending on the game, this could be "dealer", "idle", "active", ...
... other, depending on the game: points, money, etc.
methods
... very dependent on the game being played
Game
the overall monitor for the game
data
roster -- list of players
deck -- see Deck class above
... other, depending on the game: round, player to play next, etc.
Some of these overlap a bit, such as "Deck.deal" and "Hand.draw".
One of the design decisions you face is to choose which entity will drive an interaction between two objects.
As for implementation, I do suggest that you make your basic operations a lot simpler.
For the desk, initialize by generating all 52 cards with a nested list comprehension.
shuffle the deck, and then use list slicing to deal the cards. For instance, to deal 5 cards to each player:
def deal(n):
take = deck[:n]
deck = deck[n:]
return take
# elsewhere, to drive the initial dealing ...
for player in roster:
player.hand = deck.deal(5)
Simply reduce the interactions to match the way you talk about the game: "deal each player five cards" should look just like that in the code. Bury the mechanics within each class.

"For" loop Python code - does this look right/acceptable?

I would like to create a "for" loop (in Python 2). I have a list of obstacles and for each obstacle, if they are true (i.e. exist and appear in the list) I would like to append them to a list called "tests" and call a function called "obstacle_detection" (which deals with what happens when an obstacle is detected) (and I use "tests" later). This is part of a much larger program and I can't quite tell whether it's working, so I was wondering if anyone would be able to tell me if it makes sense? Or advise me of a better way there might be of doing this?
obstacles = [obstacle, obstacle1, obstacle2]
tests = []
counter = 0
for obstacle in obstacles:
tests.append(0)
tests[counter] = obstacle_detection(obstacle, pos)
counter = counter + 1
Your code possibly makes sense, depending on how you define obstacles and obstacle_detection.
As it is, you could write your code this way :
tests = [obstacle_detection(obstacle, pos) for obstacle in obstacles]
It creates a new list automatically, with the same length as obstacles and filled with obstacle_detection values for each obstacle.

Use all coordinates in a grid except with certain value

For a minesweeper I have created a board using python and pygame. When you flagged all bombs, you win. I have separate functions that contain the (randomised) bomb positions, and create the numbers around the bombs(on the proper coordinates). How do I make sure it checks the coordinates 0 to GRID_TILES(the maximum range) with the exception of all bomb locations? As those should remain flagged.
I got a function where when you click a bomb, you get shown the entire board. I want the same except for when the coordinates are in my BOMBS[].
def show_board():
for x in range(0,GRID_TILES):
for y in range(0, GRID_TILES):
"when" not in BOMBS:
draw_item(CELLS[x][y], x, y, (x+1,y+1))
I want to know if there is a "when" function, and how I could implement it.
If I understand you correctly, then the following should work:
If BOMBS is a list of tuples, then the following test should work if (x, y) not in BOMBS:
The in operator works on lists, as well as dicts, sets and tuples - anything that's iterable actually. In general, using it on lists is not such a great idea, because it needs to look through the whole list, in the worst case, to find an element. But for such small lists, it should not be a problem. If you find that it is, make BOMBS be a set and you should be good.

Why use List instead of Tuple to represent a game board?

In the Tetris game in the PyGame book, they create a board using:
board = []
for i in range(BOARDWIDTH):
board.append([BLANK] * BOARDHEIGHT)
return board
While that's fine, a list of lists, I was thinking about how they usually represent that in Java and other languages, as an array with set index - for example, int board[][] = new int[8][8]; // create 64 integers (a 2d array example).
From what I understand, tuples are more similar to the array (vs List which is more like ArrayList or LinkedList of Java). They have set number of elements and can't be added to, and hold a set number of items.
Why would we not create a tuple of tuples for a board, for example
board = ( (BLANK,)*10 ,)*10
Do they use lists of lists for some optimization in Python's internal representation of the board, or just because they assume users know List more commonly than Tuple?
This has the added benefit of being functional and making immutable objects. If you want to make a board with a state in which you moved in tic tac toe for example, you could try something like:
tictac = ((0,0,0),)*3
vals = (tuple((tictac[r][c]) if r!=1 or c!=1 else 'x' for (r,row) in enumerate(tictac)) for c in range(3))
for i in vals: print i
to move a 1 to the center.
List comprehensions are quite flexible in Python and this is more functionally-correct.
The difference between list and tuple in python is that tuple is immutable. That's why you can't change the size of a tuple (since you can't change it at all).
So the reason one normally would chose a list in this case is that you normally want to change the contents of the game board.
The benefits of having a matrix of fixed size may be slim. One could of course argue that one might get some performance benefit, but AFAIK the built in types are anyway of dynamic size in the sense that the size is determined at runtime and each time you access the container. In this aspect the list and tuple does not differ, that is when you write board[3][4] python would first access board check if it's length is larger than 3 so it can deliver the [3] element, then that element happens to be a list/tuple which is then checked for it size so it's larger than 4 so it can deliver the [4] element.
One could also argue that it would be for safety reasons or that it's "good practice" to not allow the board to be resized, and I could agree on that. What one then would do to allow modification is to wrap it all in a class that doesn't allow for resizing. One should bear in mind however that python doesn't provide very hard protection of classes that prohibit you from fiddling with internals - rather python trusts the programmer to not doing ugly things instead of trying to forbid.

Categories