// Manages snake body segments and movement mechanics // Handles growth, collision detection, and rendering class Snake { field Array body; field int length; field int maxLength; field int direction; field int size; field Point head; // create snake with initial length at center screen constructor Snake new() { let maxLength = 200; let length = 3; let size = 8; let direction = 4; // right let body = Array.new(maxLength); // initialize head at screen center (adjusted for header area) let head = Point.new(256, 144); let body[0] = head; // create initial body segments let body[1] = Point.new(248, 144); let body[2] = Point.new(240, 144); do draw(); return this; } // free memory method void dispose() { var int i; var Point segment; let i = 0; while (i < length) { let segment = body[i]; do segment.dispose(); let i = i + 1; } do body.dispose(); do Memory.deAlloc(this); return; } // draw entire snake as solid squares method void draw() { var int i; var Point segment; do Screen.setColor(true); let i = 0; while (i < length) { let segment = body[i]; do Screen.drawRectangle(segment.getX(), segment.getY(), segment.getX() + size - 1, segment.getY() + size - 1); let i = i + 1; } return; } // erase tail segment method void eraseTail() { var Point tail; let tail = body[length - 1]; do Screen.setColor(false); do Screen.drawRectangle(tail.getX(), tail.getY(), tail.getX() + size, tail.getY() + size); return; } // move snake one step forward with optional growth method void move(boolean grow) { var int i; var Point newHead; var Point oldTail; var int newX, newY; // calculate new head position based on direction let newX = head.getX(); let newY = head.getY(); if (direction = 1) { let newY = newY - 8; } // up if (direction = 2) { let newY = newY + 8; } // down if (direction = 3) { let newX = newX - 8; } // left if (direction = 4) { let newX = newX + 8; } // right // create new head first let newHead = Point.new(newX, newY); if (grow) { // growing: shift everything back and add new head let i = length; while (i > 0) { let body[i] = body[i - 1]; let i = i - 1; } let body[0] = newHead; let head = newHead; let length = length + 1; // draw new head only do Screen.setColor(true); do Screen.drawRectangle(head.getX(), head.getY(), head.getX() + size - 1, head.getY() + size - 1); } else { // not growing: move tail to front as new head let oldTail = body[length - 1]; // erase old tail first do Screen.setColor(false); do Screen.drawRectangle(oldTail.getX(), oldTail.getY(), oldTail.getX() + size - 1, oldTail.getY() + size - 1); // shift body segments back let i = length - 1; while (i > 0) { let body[i] = body[i - 1]; let i = i - 1; } // dispose old tail and use new head do oldTail.dispose(); let body[0] = newHead; let head = newHead; // draw new head do Screen.setColor(true); do Screen.drawRectangle(head.getX(), head.getY(), head.getX() + size - 1, head.getY() + size - 1); } return; } // change direction (prevent reverse moves) method void setDirection(int newDirection) { // prevent moving directly backwards if (((direction = 1) & (newDirection = 2)) | // up -> down ((direction = 2) & (newDirection = 1)) | // down -> up ((direction = 3) & (newDirection = 4)) | // left -> right ((direction = 4) & (newDirection = 3))) { // right -> left return; } let direction = newDirection; return; } // check wall collision (adjusted for header area) method boolean hitWall() { return (head.getX() < 8) | (head.getX() > 496) | (head.getY() < 33) | (head.getY() > 240); } // check self collision method boolean hitSelf() { var int i; var Point segment; let i = 1; // skip head (index 0) while (i < length) { let segment = body[i]; if (head.equals(segment)) { return true; } let i = i + 1; } return false; } // get head position method Point getHead() { return head; } // get current length method int getLength() { return length; } // get current direction method int getDirection() { return direction; } }