~cpp 
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;
class SnakeCell {
	public int snakeCellX;
	public int snakeCellY;
	public SnakeCell(int x, int y) {
		snakeCellX = x;
		snakeCellY = y;
	}
};
class Snake {
	public static final int LEFT = 1;
	public static final int RIGHT = 2;
	public static final int UP = 3;
	public static final int DOWN = 4;
	private final int snakeCellXRange;
	private final int snakeCellYRange;
	private Vector snakeCellVector;
	private int snakeHeadIndex;
	private int snakeDirection;
	public Snake(int length, int xRange, int yRange) {
		snakeCellXRange = xRange;
		snakeCellYRange = yRange;
		snakeCellVector = new Vector();
		for(int i = length ; i >= 1 ; i--)
			snakeCellVector.addElement(new SnakeCell(i, 1));
		snakeHeadIndex = 0;
		snakeDirection = Snake.RIGHT;
	}
	public int length() {
		return snakeCellVector.size();
	}
	public SnakeCell getSnakeCell(int index) {
		return (SnakeCell)snakeCellVector.elementAt((snakeHeadIndex + index) % length());
	}
	public int getDirection() {
		return snakeDirection;
	}
	public void setDirection(int direction) {
		snakeDirection = direction;
	}
	public boolean checkGameOver() {
		SnakeCell head;
		SnakeCell cell;
		head = getSnakeCell(0);
		if(head.snakeCellX < 0 || head.snakeCellY > snakeCellXRange - 1
		|| head.snakeCellY < 0 || head.snakeCellY > snakeCellYRange - 1)
			return false;
		int length = length();
		for(int i = 1 ; i < length ; i++) {
			cell = getSnakeCell(i);
			if(cell.snakeCellX == head.snakeCellX && cell.snakeCellY == head.snakeCellY)
				return false;
		}
		return true;
	}
	public boolean go() {
		SnakeCell prevHead = getSnakeCell(0);
		snakeHeadIndex = (snakeHeadIndex + length() - 1) % length();
		SnakeCell currentHead = getSnakeCell(0);
		currentHead.snakeCellX = prevHead.snakeCellX;
		currentHead.snakeCellY = prevHead.snakeCellY;
		if(snakeDirection == Snake.LEFT)
			currentHead.snakeCellX--;
		else if(snakeDirection == Snake.RIGHT)
			currentHead.snakeCellX++;
		else if(snakeDirection == Snake.UP)
			currentHead.snakeCellY--;
		else if(snakeDirection == Snake.DOWN)
			currentHead.snakeCellY++;
		return checkGameOver();
	}
};
class SnakeBiteCanvas extends Canvas {
	private final int boardWallWidth = 4;
	private final int snakeCellWidth = 4;
	private final int canvasWidth;
	private final int canvasHeight;
	private final int boardX;
	private final int boardY;
	private final int boardWidth;
	private final int boardHeight;
	private final int boardInnerX;
	private final int boardInnerY;
	private final int boardInnerWidth;
	private final int boardInnerHeight;
	private Snake snake;
	private boolean pause;
	private boolean drawAll;
	private boolean printScore;
	private boolean gameOver;
	public Command pauseCommand;
	public Command restartCommand;
	
	public SnakeBiteCanvas() {
		canvasWidth = getWidth();
		canvasHeight = getHeight();
		boardWidth = canvasWidth - 6 - (canvasWidth - 6 - boardWallWidth * 2) % snakeCellWidth;
		boardHeight = boardWidth / 10 * 8 - (boardWidth / 10 * 8 - boardWallWidth * 2) % snakeCellWidth;
		boardX = (canvasWidth - boardWidth) / 2;
		boardY = (canvasHeight - boardHeight) /2;
		
		boardInnerX = boardX + boardWallWidth;
		boardInnerY = boardY + boardWallWidth;
		boardInnerWidth = boardWidth - boardWallWidth * 2;
		boardInnerHeight = boardHeight - boardWallWidth * 2;
		
		snake = new Snake(5, boardInnerWidth / snakeCellWidth, boardInnerHeight / snakeCellWidth);
		pause = true;
		drawAll = true;
		printScore = false;
		gameOver = false;
	}
	public void drawBoard(Graphics g) {
		g.setColor(0xFFFFFF);
		g.fillRect(0, 0, canvasWidth, canvasHeight);
		g.setColor(0x000000);
		g.fillRect(boardX, boardY, boardWidth, boardHeight);
	}
	public void clearBoard(Graphics g) {
		g.setColor(0xFFFFFF);
		g.fillRect(boardInnerX - 1, boardInnerY - 1, boardInnerWidth + 2, boardInnerHeight + 2);
	}
	public void drawSnakeCell(Graphics g, SnakeCell cell) {
		g.fillRect(boardInnerX + snakeCellWidth * cell.snakeCellX,
			boardInnerY + snakeCellWidth * cell.snakeCellY,
			snakeCellWidth, snakeCellWidth);
	}
	public void paint(Graphics g) {
		if(drawAll) {
			drawBoard(g);
			drawAll = false;
		}
		clearBoard(g);
		int length = snake.length();
		SnakeCell cell;
		g.setColor(0x000000);
		for(int i = 0; i < length ; i++) {
			cell = snake.getSnakeCell(i);
			drawSnakeCell(g, cell);
		}
		if(printScore) {
		}
		if(gameOver) {
			g.drawString("Game Over!!", canvasWidth / 2, canvasHeight, Graphics.HCENTER | Graphics.BOTTOM);
		}
	}
	
	public void keyPressed(int keyCode) {
		if(!pause && !gameOver) {
			int gameAction = getGameAction(keyCode);
			if(gameAction == Canvas.LEFT && snake.getDirection() != Snake.RIGHT)
				snake.setDirection(Snake.LEFT);
			else if(gameAction == Canvas.RIGHT && snake.getDirection() != Snake.LEFT)
				snake.setDirection(Snake.RIGHT);
			else if(gameAction == Canvas.UP && snake.getDirection() != Snake.DOWN)
				snake.setDirection(Snake.UP);
			else if(gameAction == Canvas.DOWN && snake.getDirection() != Snake.UP)
				snake.setDirection(Snake.DOWN);
			else
				return;
			if(snake.go() == false) {
				this.removeCommand(pauseCommand);
				this.addCommand(restartCommand);
				gameOver = true;
			}
		
			repaint();
		}
	}
	public void start() {
		pause = false;
	}
	public void pause() {
		pause = true;
	}
	public void restart() {
		snake = new Snake(5, boardInnerWidth / snakeCellWidth, boardInnerHeight / snakeCellWidth);
		pause = true;
		drawAll = true;
		printScore = false;
		gameOver = false;
		repaint();
	}
};
public class SnakeBite extends MIDlet implements CommandListener {
	private Display display;
	private SnakeBiteCanvas canvas;
	private Command startCommand;
	private Command pauseCommand;
	private Command restartCommand;
	private Command exitCommand;
	
	public SnakeBite() {
		display = Display.getDisplay(this);
		canvas = new SnakeBiteCanvas();
		startCommand = new Command("Start", Command.SCREEN, 1);
		pauseCommand = new Command("Pause", Command.SCREEN, 1);
		restartCommand = new Command("Restart", Command.SCREEN, 1);
		exitCommand = new Command("Exit", Command.EXIT, 1);
		canvas.pauseCommand = pauseCommand;
		canvas.restartCommand = restartCommand;
		
		canvas.addCommand(startCommand);
		canvas.addCommand(exitCommand);
		canvas.setCommandListener(this);
	}
	
	public void startApp() {
		display.setCurrent(canvas);
	}
	
	public void pauseApp() {
	}
	
	public void destroyApp(boolean unconditional) {
		display = null;
		canvas = null;
		exitCommand = null;
	}
	
	public void commandAction(Command c, Displayable d) {
		if(c == startCommand) {
			canvas.removeCommand(startCommand);
			canvas.addCommand(pauseCommand);
			canvas.start();
		}
		else if(c == pauseCommand) {
			canvas.removeCommand(pauseCommand);
			canvas.addCommand(startCommand);
			canvas.pause();
		}
		else if(c == restartCommand) {
			canvas.removeCommand(restartCommand);
			canvas.addCommand(startCommand);
			canvas.restart();
		}
		else if(c == exitCommand) {
			destroyApp(true);
			notifyDestroyed();
		}
	}
};