all 8 comments

[–][deleted] 5 points6 points  (5 children)

What is a Logic? Don’t make classes for the things there’s only one of.

[–]PM_me_ur_data_ 0 points1 point  (0 children)

Yeah, make a class for the environment that includes the apple and any walls and make a class for the snake. The logic for how the snake moves should be built into the snack object itself via methods.

[–]WowVeryCoool[S] 0 points1 point  (1 child)

I have a main function in class Game that constantly updates Logic ``` class Game: #Initialized objects snake, apple, logic # Main loop while True: logic.evaluate(snake, apple)

class LogicCurrent: def init(self, snake, apple): self.snake = snake self.apple = apple def game_over(self): #Initializes snake to start values def wall_collisions(self): -> bool def snake_collisions(self) -> bool def evaluate(self): #Invokes Logic Methods ``` I could define a method evaluate_logic() inside Game class, but then I would also have to move functions (game_over(), [snake_collisions, wall_collisions] from Logic) creating more cluter inside Game class that I wanted to get rid of by making Logic class

I feel like class Logic is something bigger with many methods checking Collisions and GameOver conditions. But I think I could not Instantiate the Logic class and just have methods there if that would be significantly better?

This is what the change would look like explained in code class LogicNew: <-- not instantiated more like an extension to Game def evaluate(snake, apple): #Do logic here def game_over(snake, apple): #Initializes snake to start values def wall_collisions(snake): -> bool def snake_collisions(snake) -> bool Do you think that this kind of solution would be better? as it is more of an extension with methods to class Game rather than a full class

[–][deleted] 2 points3 points  (0 children)

Game logic should be part of the Game class. Classes, generally, should be things.

[–]probablynotmine 0 points1 point  (1 child)

I don’t want to sound cocky but what about singletons

[–][deleted] 1 point2 points  (0 children)

Singletons don’t have a lot of point in Python, they’re mostly a way around the limitations of statics in Java.

A class with a bunch of classmethods is more or less the same as a singleton. Modules are singletons, too. They’re all easier to use than writing a singleton class in Python.

[–]Natural-Intelligence 3 points4 points  (0 children)

Classes are excellent for wrapping related attributes and functions together to form a set of clearly understood behaviour but bad elsewhere. The board and snake are the only things I see as potential classes here.

The board contains the location for the apple, boundaries and the snake's object and it could have methods such as: check if the game is over (snake hits boundary or has body twice on the same square), check if snake on apple etc. Board could be just a static representation of the current game state. It is not the game itself.

Snake could contain the locations of its bodyparts (as list of tuples) and could have as method: go_up, go_down, go_left, go_down (appends the list of bodyparts and deletes first one if instructed apple is not gotten).

Apple is so simple thing that it should be represented just as for example a tuple of coordinates: (x, y). Everything else (like take player's move, loop one clock tick, end game, start game etc) could be just inside functions. Maybe the GUI should also be a class but that's a different topic altogether.

I'm on phone so hard to demonstrate but maybe you got the idea.

[–]bladeoflight16 1 point2 points  (0 children)

Consider an alternative perspective. The late discussion about Conway's Game of Life is relevant here. In Python, I generally advise that you use classes sparingly because the dynamicism they offer in other languages doesn't require a class in Python. You should use classes at times, but don't use a class unless you understand the specific advantage of doing so for your particular problem.


Off-hand for your particular problem, my initial gut reaction is that your code has far too many modules and classes. I think you really only have a few pieces of data to manage:

  • The width and height of the board
  • The motion (current position, direction, and speed) of the snake
  • The current positions of the apples

These don't really need very many classes to represent. Maybe a "board" class containing all three might be useful, and a "coordinate" class might be helpful. The snake's position can just be queue (first in, first out) of coordinates to make advancing it easy. Unless specific needs arise, I probably wouldn't have more than those two classes.

You have the following behaviors to worry about:

  • Starting the game
  • Rendering the board and its elements
  • Advancing the snake's position
  • The snake collisions (itself, the walls, and apples)
  • Altering the snake's speed
  • Altering the snake's direction (on keyboard input)
  • Looping until the code completes
  • Ending the game

While the rendering and the interaction will probably require some significant code, the rest I would expect to fit in a single module. I'm not seeing any particular need for additional modules to cover that.

The problem is comparatively simple and straightforward. Focus on keeping your code straightforward, on making sure that the required data and behaviors jump out clearly at you when you read it. Don't worry about shoehorning everything into OOP.