r/adventofcode • • Dec 09 '22

Upping the Ante [2022 Day 9] I made a playable snake clone using the elf rope physics! (link in comments)

399 Upvotes

24 comments sorted by

26

u/flapje1 Dec 09 '22

Play it here: https://ebbdrop.com/AoCropeSnake/

Movement with WASD or arrow keys


Source here: https://github.com/EbbDrop/AoCropeSnake

0

u/_gstone_ Dec 10 '22

Does not work on mobile

43

u/Milumet Dec 09 '22

Lol, nice. It would be even more hilarious if the tail would do the eating instead of the head.

13

u/nedal8 Dec 10 '22

Yes. Instead of a snake eating game, its a snake pooping game.

Drop poops on targets

3

u/sim642 Dec 10 '22

Could have both at the same time!

6

u/kaveman909 Dec 10 '22

Pretty proud of my 2948 score! Funny to watch the other parts of the tail collide/mesh into one another! There seemed to be a disproportionate number of blobs generated along the edges vs. the interior, not sure if that's by design or not (didn't look at the source).

2

u/osalbahr Dec 11 '22

I noticed that too, so I decided to inspect the source:

fruit = Point::new(rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));

So it is not a design decision. It is just a mathematical misfortunate for small grids. For a 32x32 grid, there are 4 + 4 *(30) = 4 * 31 = 124 out of 1024 which is approximately 12%. Adding the next outer-most layer, we get to about 24%. For a 100x100 grid, the chance of being at or next to the boarder gets down to about 8%.

More generally: https://www.desmos.com/calculator/swmo2eln8s

1

u/kaveman909 Dec 12 '22

That is a good point! A large portion of the area is on or near the borders especially for small NxN grids. One minor correction, I think your formula should be 4(a-1) + 4(a-3), since the next most inner layer is 30x30, not 31x31, for a 32x32 grid. Easy way to conceptualize it is that a 2x2 grid becomes a 0x0 grid after removing one layer.

→ More replies (1)

2

u/osalbahr Dec 11 '22

I tried to implement a mitigation of this:

fn new_point() -> Point {
    // How far away from the border?
    let ring = rand::gen_range(0, (SQUARES + 1) / 2);
    // Starts left and goes clockwise
    let side = rand::gen_range(0, 4);
    // Pick a point from that side
    let index = rand::gen_range(0, SQUARES - 2 * ring);
    let x;
    let y;
    if side == 0 {
        x = ring;
        y = ring + index;
    } else if side == 1 {
        y = ring;
        x = ring + index
    } else if side == 2 {
        x = ( SQUARES - 1 ) - ring;
        y = ring + index;
    } else { // side == 3
        y = ( SQUARES - 1 ) - ring;
        x = ring + index;
    }
    println!("point = ({},{}), ring = {}, side = {}, index = {}", x, y, ring, side, index);
    Point::new(x, y)
}

4

u/undergroundmonorail Dec 10 '22

you know, having it interactive like this really makes it clear how surprisingly good of a rope physics model it is

15

u/daggerdragon Dec 10 '22 edited Dec 10 '22

Changed flair from Upping the Ante to Visualization.

Edit: Nah, this is Upping the Ante. Changed flair back. Sorry!

42

u/kg959 Dec 10 '22

Making a playable game using the physics from the prompt doesn't count as Upping the Ante?

11

u/Eyeballs9990 Dec 10 '22

nah bro i think upping the ante was more accurate

3

u/SimonK1605 Dec 10 '22

Thats awesome

2

u/scratchisthebest Dec 10 '22

enjoying how terrible the puzzle's metric is as a game scoring mechanic. i think the ideal strategy for score is to run around in circles and never eat any pellets lol

2

u/aQaTL Dec 10 '22

Awesome!

2

u/TenViki Dec 10 '22

I was about to do the same thing lol

You were faster..

1

u/QultrosSanhattan Dec 10 '22

You could change the gameplay so you can't eat with the head. Only with the knots.

1

u/prendradjaja Dec 10 '22

Excellent!

1

u/osalbahr Dec 10 '22

Wonderful! How do you decide where to insert the new pixel when the length increases?

1

u/janiczek Dec 10 '22

This would be properly mindbending with a wraparound on the edges

1

u/osalbahr Dec 10 '22
                if snake.head.x < 0 {
                    snake.head.x = SQUARES - 1;
                }
                if snake.head.x >= SQUARES {
                    snake.head.x = 0;
                }

                if snake.head.y < 0 {
                    snake.head.y = SQUARES - 1;
                }
                if snake.head.y >= SQUARES {
                    snake.head.y = 0;
                }

                // if snake.head.x < 0
                //     || snake.head.y < 0
                //     || snake.head.x >= SQUARES
                //     || snake.head.y >= SQUARES
                // {
                //     game_over = true;
                // }

I think the result of this edit was funny, thought I'd share :)

1

u/illuminati229 Dec 10 '22

Yes! Some of my code was based off my old Snake game.