A question about the logic of making a "Snake" game

  • Thread starter Thread starter Jamin2112
  • Start date Start date
  • Tags Tags
    Game Logic
Click For Summary

Discussion Overview

The discussion revolves around the logic and implementation of generating food locations in a "Snake" game. Participants explore various methods for ensuring that food appears in valid locations that do not overlap with the snake's body, considering both efficiency and randomness in their approaches.

Discussion Character

  • Exploratory
  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant suggests two methods for placing food: randomly selecting a location and checking for collisions with the snake, or using the snake's body positions to determine valid food locations.
  • Another participant argues that the first method is sufficient, citing their own experience with a similar game where it performed well.
  • Some participants propose a forward-seeking approach from a random point in the snake's body to find free spaces, arguing that this method limits the number of iterations needed to find a valid location.
  • Concerns are raised that using a forward-seeking method may lead to food being placed too close to the snake, potentially limiting gameplay variety.
  • Suggestions are made to introduce a random jitter factor to the forward-seeking method to enhance unpredictability in food placement.
  • One participant mentions the idea of stepping through board locations in a pseudo-random order to improve randomness while still ensuring valid placements.

Areas of Agreement / Disagreement

Participants express differing opinions on the best method for placing food, with some favoring random selection and others advocating for a more structured approach. The discussion remains unresolved, with multiple competing views on the effectiveness of each method.

Contextual Notes

Participants highlight potential inefficiencies in random selection as the snake grows longer and discuss the implications of food placement on gameplay dynamics.

Jamin2112
Messages
973
Reaction score
12
I've started to make a "Snake" game (example: http://www.kongregate.com/games/uchiha/classic-snake-game) and reached a dead end. I'm not sure the programmatically best way of figuring out where the snake's "food" should next appear. It should of course appear anywhere on the screen that doesn't collide with the snake. I therefore think there are 2 procedures:

  • (1) Pick a random location on the screen. If this location lies somewhere on the snake, then pick another random location. Do this until you find a proper location.
  • (2) Use the positions of the links that compose the snake to figure out a proper next random location for the food.

The first one is inefficient, especially when the snake is long. The second one, I don't know how to write. Any ideas for how I can write the second one?

By the way, here's what I have so far:

The snakegame class is: jaminweb.com/Snakegame.html

Code:
        $(document).keydown(function(e)
        {
            switch(e.which)
            {
                case 37: // left arrow key
                  s.redirect(3);
                  break;

                case 38: // up arrow key
                  s.redirect(4);
                  break;

                case 39: // right arrow key
                   s.redirect(1)
                   break;

                case 40: // down arrow key
                   s.redirect(2);
                   break;

                default: return; // exit this handler for other keys
            }
            e.preventDefault(); // prevent the default action (scroll / move caret)
         });

        function snakegame(C, C_h, C_w)
        {
                /* NOTE TO SELF: C is a Raphel object. Can't find a method to return the height
                   and width of a Raphael object in the documentation: 
                   [PLAIN]http://raphaeljs.com/reference.html#Raphael.[/PLAIN] 
                   Using C_h and C_w for now, but should probably change it later.
                */
                
                this.linkSize = 30; // size of a snake unit, in pixels
                
                this.food = C.rect(10, 30, this.linkSize, this.linkSize);
                this.food.attr("fill","#39275b")
                this.food.glow();
                
                /* On instantiation, the snake direction is down and has 1 link */
                this.dy = this.linkSize;
                this.dx = 0;
                this.link = C.rect(C_h/2, C_w/2, this.linkSize, this.linkSize);
                this.link.attr("fill", "#d7a900");
                this.body = [this.link];
                
                /* Event listener for changing the direction of the
                   snake with arroy keys on the keyboard
                */
                this.redirect = function(dirnum)
                {
                    switch (dirnum)
                    {
                        /*
                            dirnum corresponds to
                            1 ---> right
                            2 ---> down
                            3 ---> left
                            4 ---> up
                        */
                        case 1: 
                            this.dx = this.linkSize;
                            this.dy = 0;
                            break;
                        
                        case 2:
                            this.dx = 0;
                            this.dy = this.linkSize;
                            break;
                        
                        case 3:
                            this.dx = -this.linkSize;
                            this.dy = 0;
                            break;
                        
                        case 4:
                            this.dx = 0;
                            this.dy = -this.linkSize;
                            break;
                        
                        default: // never happens
                            break;
                    }
                            
                }
                this.move = function()
                {
                    /*
                        ...
                    */
                    var temp = this.body[0];
                    var BBhead = temp.getBBox();
                    if (BBhead.x < 0 || BBhead.x2 > C_w || BBhead.y < 0 || BBhead.y2 > C_h)
                    {
                        clearInterval(mover); 
                        return;
                    }
                    var BBfood = this.food.getBBox();
                    if (this.boxCollision(BBhead, BBfood))
                    {
                        this.moveFood();
                        this.addLink();
                    }
                    this.body[0].translate(this.dx, this.dy);
                    for (var i = 1, j = this.body.length; i < j; ++i)
                    {
                        this.body[i] = temp;
                        temp = this.body[i];
                    }
                }
                
                var mover = setInterval(this.move.bind(this), 300);   
                
                this.addLink = function()
                {
                    alert("you hit it!"); 
                }
                
                this.moveFood = function()
                {
                    
                }
                this.boxCollision = function(A, B)
                {
                    return A.x > B.x && A.x < B.x2 && A.y > B.y && A.y < B.y2;
                }

        }

It's messy, but hopefully you can see my intent and give me some ideas for how to build off what I have now.
 
Last edited by a moderator:
Technology news on Phys.org
The first method should be fine, really. I've made a similar snake game in html5 with method 1. Works perfectly.

Modern PCs don't lag much when computing a single random number.
 
Instead of doing it purely random you should pick a random point in the array and forward-seek until you find a free space. This way the upper bound is N rather than unknown. That and you don't waste cycles generating random numbers.
 
DavidSnider said:
Instead of doing it purely random you should pick a random point in the array and forward-seek until you find a free space. This way the upper bound is N rather than unknown. That and you don't waste cycles generating random numbers.

Then the piece of food will always be right near the snake. He'll be stuck in one area of the screen because the piece of food will always appear next to one of his units.
 
Jamin2112 said:
Then the piece of food will always be right near the snake. He'll be stuck in one area of the screen because the piece of food will always appear next to one of his units.

The vast majority of the time the initial space chosen will be empty, when the screen is mostly filled it's always going to be near the snake anyway. You could add a random jitter factor that says "pick the nth open spot you find" where n is a random number. You can also pick a random seek direction for less predictability.
 
Last edited:
Jamin2112 said:
Then the piece of food will always be right near the snake

You could forward-seek in steps of p locations, where p is relatively prime to the size of the playing area.

That will step through all the board locations in sequence, but in pseudo-random order.

For "more randomness", look up the "quadratic probing" technique for dealing with collisions in hash tables.
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 33 ·
2
Replies
33
Views
7K
  • · Replies 4 ·
Replies
4
Views
2K
Replies
1
Views
7K
Replies
15
Views
5K