Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Create a text based snake game in Java without Spring or Jpanel. Will have three

ID: 3602259 • Letter: C

Question

Create a text based snake game in Java without Spring or Jpanel. Will have three files (SnakeGame, SnakeBoard, & Position). The snake moves around the board until it runs into itself or goes out of bounds. No score or 'apple' for food needed.

The edge of the board is drawn with #’s

The snake is drawn with S’s.

The snake has 20 spaces horizontally and 10 spaces vertically where it can move.

The edge of the board is outside the 20 x 10 area  

Initially the snake is 2 segments long – at (1, 1) and (1, 2).  

Let the positions be 0-based. (0, 0) is the upper left.  

X grows positive to the right and y grows positive going down.

The initial board, with the 2 initial snake segments, looks like:

If the snake moves to a spot already occupied by the snake or into the edge of the board, then the game is over.

Keep track of the number of moves before the game ends.  

1) SnakeGame class which contains main() – essentially the code shown above in how to play the game

Initialize the board and snake

Initialize the number of moves made

Print the board

Continue until the game ends (snake runs into edge or itself)

Remove the oldest segment from the snake

For example, the first time, (1, 1) will be removed from the snake

Ask the user for a move (l for left, r for right, u for up, and d for down)

Move the snake twice in that direction

For example, if the user chooses ‘r’ and the last segment added to the snake was (1, 2), then add (2, 2) and (3, 2) to the snake

Right increases the x-coordinate. So (1, 2) moves to (2, 2) and (2, 2) moves to (3, 2)

I had a method in my SnakeBoard class that did a single move and called it twice. I felt this option would be more flexible if I wanted to change the game in the future.

Print the board

Increment the number of moves made

After the game is over, print the number of moves made

2) SnakeBoard class

Need some final instance variables (Width of the board, Height of the board)

2 instance variables (Array or ArrayList of Position objects – will contain all of the Positions of the Snake)

Flag to remember if snake has made an illegal move (moved onto itself or off the edge of the board and the game is over when this flag becomes true)

Constructor

Initialize the Array/ArrayList

Add first 2 snake segments to the Array/ArrayList

You should create a new Position object, set its x, y, add it to your Array/ArrayList

Then you should create a second ‘new’ Position, set its x, y, and add it to your Array/ArrayList

Do NOT try to reuse the same Position object – you’ll want to call new a second time

print method to print the board

This method will need nested loops to print the two-dimensional board

Within the loops, I checked to see if the x,y location that I was about to print was a Position in my Array/ArrayList. If it was in there, then I printed ‘S’, otherwise I printed ‘ ‘ (space).

removeSnake method to remove the oldest Position in the Array/ArrayList

moveSnake method to add one more Position to the Array/ArrayList

pass in a direction to move

use the last Position of the Snake and the direction to calculate the x, y of the new Position

add the new Position to your Array/ArrayList if it is a valid move

gameOver method that returns true if the game is over, false otherwise

validMove method that returns true if moving to x, y is okay, false otherwise

snakeHere method that returns true if the x,y you are checking is an x,y currently in your Array/ArrayList

3) Position class

Simple class that contains x, y and matching get/set methods

The following is an example of a Position class I used

package snake;

public class Position

{

private int x;

private int y;

public int getX()

{

return x;

}

public void setX(int x)

{

this.x = x;

}

public int getY()

{

return y;

}

public void setY(int y)

{

this.y = y;

}

}

Requirements:

Put System.out.println() after each call to next(). This will help you match the Test Program and make it easier to use it.

Sample Run #1: (the highlighted text is what the user types)

Explanation / Answer

Game.Java

Snake.Java

Food.java

Board.Java

Game.Java

  import java.awt.EventQueue;    import javax.swing.JFrame;    public class Game extends JFrame {    Game() {      add(new Board());      setResizable(false);      pack();        setTitle("Snake");      setLocationRelativeTo(null);      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  }    public static void main(String[] args) {        // Creates a new thread so our GUI can process itself      EventQueue.invokeLater(new Runnable() {          @Override          public void run() {              JFrame frame = new Game();              frame.setVisible(true);          }      });  }  }  

Snake.Java

  public class Snake {    // Stores the joints / body part locations for our snake  private final int[] x = new int[Board.getAllDots()];  private final int[] y = new int[Board.getAllDots()];    // Stores direction of our snake  private boolean movingLeft = false;  private boolean movingRight = false;  private boolean movingUp = false;  private boolean movingDown = false;    private int joints = 0; // Stores # of dots / joints the snake has (starts                          // with 3)    public int getSnakeX(int index) {      return x[index];  }    public int getSnakeY(int index) {      return y[index];  }    public void setSnakeX(int i) {      x[0] = i;  }    public void setSnakeY(int i) {      y[0] = i;  }    public boolean isMovingLeft() {      return movingLeft;  }    public void setMovingLeft(boolean movingLeft) {      this.movingLeft = movingLeft;  }    public boolean isMovingRight() {      return movingRight;  }    public void setMovingRight(boolean movingRight) {      this.movingRight = movingRight;  }    public boolean isMovingUp() {      return movingUp;  }    public void setMovingUp(boolean movingUp) {      this.movingUp = movingUp;  }    public boolean isMovingDown() {      return movingDown;  }    public void setMovingDown(boolean movingDown) {      this.movingDown = movingDown;  }    public int getJoints() {      return joints;  }    public void setJoints(int j) {      joints = j;  }    public void move() {      for (int i = joints; i > 0; i--) {            // Moves the joints of the snake 'up the chain'          // Meaning, the joint of the snake all move up one          x[i] = x[(i - 1)];          y[i] = y[(i - 1)];      }        // Moves snake to the left      if (movingLeft) {          x[0] -= Board.getDotSize();      }      // To the right      if (movingRight) {          x[0] += Board.getDotSize();      }      // Down      if (movingDown) {          y[0] += Board.getDotSize();      }      // And finally up      if (movingUp) {          y[0] -= Board.getDotSize();      }        // Dotsize represents the size of the joint, so a pixel of DOTSIZE      // gets added on to the snake in that direction  }   }  

Food.java

  public class Food {    private Snake snake = new Snake();  private int foodX; // Stores X pos of our food  private int foodY; // Stores Y pos of our food    // Used to determine random position of food  private final int RANDOMPOSITION = 40;    public void createFood() {        // Set our food's x & y position to a random position        int location = (int) (Math.random() * RANDOMPOSITION);      foodX = ((location * Board.getDotSize()));        location = (int) (Math.random() * RANDOMPOSITION);      foodY = ((location * Board.getDotSize()));        if ((foodX == snake.getSnakeX(0)) && (foodY == snake.getSnakeY(0))) {          createFood();      }  }    public int getFoodX() {        return foodX;  }    public int getFoodY() {      return foodY;  }  }  

Board.Java

      import java.awt.Color;  import java.awt.Dimension;  import java.awt.Font;  import java.awt.FontMetrics;  import java.awt.Graphics;  import java.awt.Toolkit;  import java.awt.event.ActionEvent;  import java.awt.event.ActionListener;  import java.awt.event.KeyAdapter;  import java.awt.event.KeyEvent;  import javax.swing.JPanel;  import javax.swing.Timer;    @SuppressWarnings("serial")  public class Board extends JPanel implements ActionListener {    // TODO: Implement a way for the player to win    // Holds height and width of the window  private final static int BOARDWIDTH = 1000;  private final static int BOARDHEIGHT = 980;    // Used to represent pixel size of food & our snake's joints  private final static int PIXELSIZE = 25;    // The total amount of pixels the game could possibly have.  // We don't want less, because the game would end prematurely.  // We don't more because there would be no way to let the player win.    private final static int TOTALPIXELS = (BOARDWIDTH * BOARDHEIGHT)          / (PIXELSIZE * PIXELSIZE);    // Check to see if the game is running  private boolean inGame = true;    // Timer used to record tick times  private Timer timer;    // Used to set game speed, the lower the #, the faster the snake travels  // which in turn  // makes the game harder.  private static int speed = 45;    // Instances of our snake & food so we can use their methods  private Snake snake = new Snake();  private Food food = new Food();    public Board() {        addKeyListener(new Keys());      setBackground(Color.BLACK);      setFocusable(true);        setPreferredSize(new Dimension(BOARDWIDTH, BOARDHEIGHT));        initializeGame();  }    // Used to paint our components to the screen  @Override  protected void paintComponent(Graphics g) {      super.paintComponent(g);        draw(g);  }    // Draw our Snake & Food (Called on repaint()).  void draw(Graphics g) {      // Only draw if the game is running / the snake is alive      if (inGame == true) {          g.setColor(Color.green);          g.fillRect(food.getFoodX(), food.getFoodY(), PIXELSIZE, PIXELSIZE); // food            // Draw our snake.          for (int i = 0; i < snake.getJoints(); i++) {              // Snake's head              if (i == 0) {                  g.setColor(Color.RED);                  g.fillRect(snake.getSnakeX(i), snake.getSnakeY(i),                          PIXELSIZE, PIXELSIZE);                  // Body of snake              } else {                  g.fillRect(snake.getSnakeX(i), snake.getSnakeY(i),                          PIXELSIZE, PIXELSIZE);              }          }            // Sync our graphics together          Toolkit.getDefaultToolkit().sync();      } else {          // If we're not alive, then we end our game          endGame(g);      }  }    void initializeGame() {      snake.setJoints(3); // set our snake's initial size        // Create our snake's body      for (int i = 0; i < snake.getJoints(); i++) {          snake.setSnakeX(BOARDWIDTH / 2);          snake.setSnakeY(BOARDHEIGHT / 2);      }      // Start off our snake moving right      snake.setMovingRight(true);        // Generate our first 'food'      food.createFood();        // set the timer to record our game's speed / make the game move      timer = new Timer(speed, this);      timer.start();  }    // if our snake is in the close proximity of the food..  void checkFoodCollisions() {        if ((proximity(snake.getSnakeX(0), food.getFoodX(), 20))              && (proximity(snake.getSnakeY(0), food.getFoodY(), 20))) {            System.out.println("intersection");          // Add a 'joint' to our snake          snake.setJoints(snake.getJoints() + 1);          // Create new food          food.createFood();      }  }    // Used to check collisions with snake's self and board edges  void checkCollisions() {        // If the snake hits its' own joints..      for (int i = snake.getJoints(); i > 0; i--) {            // Snake cant intersect with itself if it's not larger than 5          if ((i > 5)                  && (snake.getSnakeX(0) == snake.getSnakeX(i) && (snake                          .getSnakeY(0) == snake.getSnakeY(i)))) {              inGame = false; // then the game ends          }      }        // If the snake intersects with the board edges..      if (snake.getSnakeY(0) >= BOARDHEIGHT) {          inGame = false;      }        if (snake.getSnakeY(0) < 0) {          inGame = false;      }        if (snake.getSnakeX(0) >= BOARDWIDTH) {          inGame = false;      }        if (snake.getSnakeX(0) < 0) {          inGame = false;      }        // If the game has ended, then we can stop our timer      if (!inGame) {          timer.stop();      }  }    void endGame(Graphics g) {        // Create a message telling the player the game is over      String message = "Game over";        // Create a new font instance      Font font = new Font("Times New Roman", Font.BOLD, 14);      FontMetrics metrics = getFontMetrics(font);        // Set the color of the text to red, and set the font      g.setColor(Color.red);      g.setFont(font);        // Draw the message to the board      g.drawString(message, (BOARDWIDTH - metrics.stringWidth(message)) / 2,              BOARDHEIGHT / 2);        System.out.println("Game Ended");    }    // Run constantly as long as we're in game.  @Override  public void actionPerformed(ActionEvent e) {      if (inGame == true) {            checkFoodCollisions();          checkCollisions();          snake.move();            System.out.println(snake.getSnakeX(0) + " " + snake.getSnakeY(0)                  + " " + food.getFoodX() + ", " + food.getFoodY());      }      // Repaint or 'render' our screen      repaint();  }    private class Keys extends KeyAdapter {        @Override      public void keyPressed(KeyEvent e) {            int key = e.getKeyCode();            if ((key == KeyEvent.VK_LEFT) && (!snake.isMovingRight())) {              snake.setMovingLeft(true);              snake.setMovingUp(false);              snake.setMovingDown(false);          }            if ((key == KeyEvent.VK_RIGHT) && (!snake.isMovingLeft())) {              snake.setMovingRight(true);              snake.setMovingUp(false);              snake.setMovingDown(false);          }            if ((key == KeyEvent.VK_UP) && (!snake.isMovingDown())) {              snake.setMovingUp(true);              snake.setMovingRight(false);              snake.setMovingLeft(false);          }            if ((key == KeyEvent.VK_DOWN) && (!snake.isMovingUp())) {              snake.setMovingDown(true);              snake.setMovingRight(false);              snake.setMovingLeft(false);          }            if ((key == KeyEvent.VK_ENTER) && (inGame == false)) {                inGame = true;              snake.setMovingDown(false);              snake.setMovingRight(false);              snake.setMovingLeft(false);              snake.setMovingUp(false);                initializeGame();          }      }  }    private boolean proximity(int a, int b, int closeness) {      return Math.abs((long) a - b) <= closeness;  }    public static int getAllDots() {      return TOTALPIXELS;  }    public static int getDotSize() {      return PIXELSIZE;  }  }  
Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote