[.snake. game in 🐍 language]Ouch my tail!

Heres the C++ code:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include <windows.h>
#include <fstream>

using namespace std;

enum direction {STOP = 0,LEFT,RIGHT,UP,DOWN};
struct coord{
    int x;
    int y;
};
//funzioni
void setup();
void map();
void input();
void logics();
//funzioni

//variabili
bool endgame;
const int width{40},height{20};
///////////////////// 22 /////////////////////////////
coord snake,fruit,tail[50];
direction dir;
int diff,score{0},ntail{0};
char field='#',Snake='O',Fruit='F',seg='o';
//variabili
//ok
int main()
{
    srand(time(0));
    system("color 5C");
    bool replay=true;
    char yn;
    cout << "Mili: ";
    cin >> diff;
    system("cls");
    while(replay){
        setup();
        while(!endgame){
            input();
            map();
            logics();
            Sleep(diff);
        }
        cout << "Try again?(y/n): ";
        do{
            cin >> yn;
            switch(yn){
            case 'y':
                replay=true;
                break;
            case 'n':
                replay=false;
                break;
            default:{
                cout << "Invalid char: ";
            }
                break;
            }
        }
        while(yn!='y' && yn!='n');
    }
    return 0;
}

void setup(){
    endgame = false;
    dir = STOP;
    snake.x = width/2;
    snake.y = height / 2;
    fruit.x = rand() % (width-1)+1;
    fruit.y = rand() % (height-1)+1;
    ntail=0;
    score=0;
}

void map(){
    system("cls");
    for(int i=0;i<width+2;i++){
        cout << field;
    }
    cout << endl;
    for(int i=0;i<height;i++){
        for(int j=0;j<width;j++){
            if(j==0)
                cout << field;
            if(j==snake.x && i==snake.y)
                cout << Snake;
            else if(j==fruit.x && i==fruit.y){
                cout << Fruit;
            }
            else{
                bool track=false;
                for(int k=0;k<ntail;k++){
                    if(tail[k].x==j && tail[k].y==i){
                        cout << seg;
                        track=true;
                    }
                }
                if(!track)
                    cout << " ";
            }
            if(j==width-1)
                cout << field;
        }
        cout << endl;
    }
    for(int i=0;i<width+2;i++){
        cout << field;
    }
    cout << endl <<  "Score: " << score << endl;
    cout << "X: " << snake.x << " Y: " << snake.y;
}

void input(){
    if(_kbhit()){
        switch(_getch()){
        case 'a':
            dir = LEFT;
            break;
        case 'd':
            dir = RIGHT;
            break;
        case 'w':
            dir = UP;
            break;
        case 's':
            dir = DOWN;
            break;
        case 'x':
            endgame = true;
            break;
        }
    }
}
/////////////////////// 134 ////////////////////////////
void logics(){
    coord prev,prev2;
    prev=tail[0];
    tail[0]=snake;
    for(int i=1;i<ntail;i++){
        prev2=tail[i];
        tail[i]=prev;
        prev=prev2;
    }
    switch(dir){
    case LEFT:
        snake.x--;
        break;
    case RIGHT:
        snake.x++;
        break;
    case UP:
        snake.y--;
        break;
    case DOWN:
        snake.y++;
        break;
    }
    //    if (snake.x<0 || snake.x>=width || snake.y<0 || snake.y>=height){
    //    cout << "\nHit border in: " << snake.x << " " << snake.y << endl;
    //        endgame = true;
    //    }
    if (snake.x>width)
        snake.x=0;
    else if(snake.x<0)
        snake.x=width-1;
    if (snake.y>=height)
        snake.y=0;
    else if(snake.y < 0)
        snake.y=height-1;
    for(int i=0;i<ntail;i++)
        if(tail[i].x==snake.x && tail[i].y==snake.y){
            cout << "\nHit tail in: " << snake.x << " " << snake.y << endl;
            endgame=true;
        }
/////////////////////// 173 ////////////////////////////////////////////////////////
    if(snake.x==fruit.x && snake.y==fruit.y){
        score++;
        ntail++;
        fruit.x = rand()% (width-1) + 1;
        fruit.y = rand()% (height -1) + 1;
    }
}

Heres my snakeLanguage code:

import Funcs
from random import randint
import Classes 

width = 500
height = 500
snake = Classes.Snake()

fruit = Classes.Fruit(12.5,12.5)

def setup():
    noStroke()
    size(width,height)
    rectMode(CENTER)
    ellipseMode(CENTER)
    frameRate(5)
def draw():
    strokeWeight(1)
    stroke(2550,0,0)
    point(width>>1,height>>1)
    background(240,221,7)
    Funcs.mapp()
    AllLogi()
   

def AllLogi(): 
   
    snake.keyPressed()
    snake.logic()
    prevH = snake.vec
    fruit.Show()
    snake.Show()
############## 16 ############################
    if dist(snake.vec.x,snake.vec.y,fruit.vec.x,fruit.vec.y) < 12.5:
         fruit.respawn()
         snake.score += 1
         snake.tail.append(snake.vec)

my classes:

from random import randint

class Snake:
    def __init__(self):
        self.step = 25
        self.vec = PVector(float((500>>1) + (self.step>>1)),float((500>>1) + (self.step>>1)))
        self.score = 0
        self.tail = []
        self.dir = "STOP"
                
    def Show(self):
        fill(255)     
        rect(self.vec.x,self.vec.y,25,25)
        fill(255,0,0)
        textSize(20)
        text(self.score,self.vec.x-6.25,self.vec.y+6.25)
        fill(0)    
        for i in range(0,len(self.tail)):
            rect(self.tail[i].x,self.tail[i].y,22,22)                    
        
    def keyPressed(self):
        if key == 'w' or key == 'W':
            self.dir = "UP"
        elif key == 's' or key == 'S':
            self.dir = "DOWN"
        elif key == 'a' or key == 'A':
            self.dir = "LEFT"
        elif key == 'd' or key == 'D':
            self.dir = "RIGHT"                    
            
    def logic(self):
######################## 31 ####################
        if len(self.tail) > 0:
            prev = self.tail[0]
            self.tail[0] = self.vec
            for i in range(1,len(self.tail)):
                prev2 = self.tail[i]
                self.tail[i] = prev
                prev = prev2
            
        if self.dir == "UP":
            self.vec.y -= self.step    
        elif self.dir == "DOWN":
            self.vec.y += self.step
        elif self.dir == "LEFT":
            self.vec.x -= self.step
        elif self.dir == "RIGHT":
            self.vec.x += self.step
        if self.vec.x > 500:
            self.vec.x = self.step>>1
        if self.vec.x < 0:
            self.vec.x = 499 - (25>>1)
        if self.vec.y > 500:
            self.vec.y = self.step>>1
        if self.vec.y < 0:
            self.vec.y = 499 - (25>>1)
        
class Fruit:
    def __init__(self,x,y):
        self.vec = PVector(x,y)
        
    def Show(self):
        fill(255,0,0)
        ellipse(self.vec.x,self.vec.y,10,10)
        
    def respawn(self):
        newX=randint(1,41) * 12.5
        while newX%25 == 0 or newX > 487.5:
            newX=randint(1,40) * 12.5
        newY=randint(1,41) * 12.5
        while newY%25 == 0 or newY > 487.5:
            newY=randint(1,40) * 12.5
        self.vec.x = newX
        self.vec.y = newY

my function to draw map:

def mapp():
    for num in range(-1,500,25):
        stroke(255)
        line(num,0,num,500)
        line(0,num,500,num)

C++: ( look for lines /////////////////////// 173 //////////////////////////////////////////////////////// like this)
line 22 i declare the array of 50 uninitialized tails (garbage data)
134. where i process tails info
173. What happens if i eat a fruit
Python: (look for lines ######################## 31 #################### like this)
16. waht happens when i collect fruit
31.Tail infos

I am appending the actual head position becausei i just need to add a space in the list/array, bc n C++ i have an unitialized array, and this makes me think it doesnt matter what PVector I append (maybe i just havent seen something in the c++ code bc it seemed obv to me but I forgot to wirte, this is why Im looking for an external pov)

1 Like

Hi Sky, could you copy and paste it without the line numbers, please :stuck_out_tongue:. Try ctrl + A?
(Both the C++ and Python ones)

yup, I thought ppl couldnt copy numbers.
Happy First Jan :fireworks:

Ok, so the problem is that every time you add a new tail piece, you are adding it to where the snake is now–rather than at the end of the tail.

Every time the snake picks up the fruit, you are adding the current position of the head of the snake to the snake–but that is already a part of the snake, so you only ever end up with the head being displayed as all of the tail pieces are there.

One solution would be to add the current position (after having moved) to the head of the tail but don’t shift all the other tail pieces forward if a fruit is eaten.

I made a little diagram in Excel to try and explain this: snakeDiagram

Happy new year! :tada:

Feel free to ask if you don’t understand.

1 Like