# snake.pl by ArZa : Snake game # This program is free software: you can modify/redistribute it under the terms of # GNU General Public License by Free Software Foundation, either version 3 or later # which you can get from . # This program is distributed in the hope that it will be useful, but without any warranty. weechat::register("snake", "ArZa ", "0.1", "GPL3", "Snake game", "", ""); weechat::hook_command("snake", "Snake game\n Keys: Arrow keys to move n: new game p: pause q: quit \nNo walls", "", "", "", "snake_cmd", ""); my ($buffer,$hook,$dir,$r,$c,$speed,$score,$prevdir,$pause,$level,@tail,@table,@coords); my ($rows,$cols,$length)=(24,38,9); my $b=weechat::color("bold"); my $n=weechat::color("reset"); my $v=weechat::color("lightblue,blue"); my $food=weechat::color("green")."<>".$n; my $empty=" "; my $head=weechat::color("lightgreen,lightblue")."`´".$n; my $dead=weechat::color("lightgreen,lightblue")."><".$n; $tail[1]="${v}══${n}"; $tail[2]="${v}║║${n}"; $tail[3]="${v}╔╔${n}"; $tail[5]="${v}╗╗${n}"; $tail[7]="${v}╚╚${n}"; $tail[9]="${v}╝╝${n}"; sub print_line { my $add = $_[1] || ""; # print a specific line weechat::print_y($buffer, $_[0]+1, "│".join("", @{$table[$_[0]]})."│ $add"); } sub redraw { # redraw the whole screen weechat::print_y($buffer, 0, "┌" . "─" x (2*$cols+2) . "┐"); for(my $i=0; $i<=$#table; $i++){ print_line($i); } weechat::print_y($buffer, $rows+2, "└" . "─" x (2*$cols+2) . "┘"); weechat::print_y($buffer, $rows+3, " Score: $score $level"); } sub hook { # 0 -> stop, 1 -> rehook (speed changed) weechat::unhook($hook) if $hook; $hook = $_[0] ? weechat::hook_timer($speed, 0, 0, "move", "") : undef; return weechat::WEECHAT_RC_OK; } sub tail { # direction -> print the right type of tail for the previous spot (yanetut) if($dir==$prevdir){ $table[$coords[-2]][$coords[-1]]=$tail[abs($dir)]; } # going straight else{ $table[$coords[-2]][$coords[-1]]=$tail[$prevdir-$dir+6]; } # turned print_line($coords[-2]); } sub init_snake { # (re)start @coords=(); # reset $speed=140; $score=0; $r=5; $c=$length; $pause=0; $level=""; $dir=$prevdir=1; for my $i (0..$rows){ # empty table for my $j (0..$cols){ $table[$i][$j]=$empty; } } for my $i (0..$length){ # add the snake $table[5][$i]=$tail[1]; push(@coords, (5,$i)); } $table[5][$length]=$head; $table[12][19]=$food; # first food redraw(); hook(1); } sub snake_cmd { # /snake $buffer=weechat::buffer_search("perl", "snake"); # find the buffer if(!$buffer){ # if not found $buffer=weechat::buffer_new("snake", "", "", "hook", ""); # create it weechat::buffer_set($buffer, "title", "Snake | Keys: arrows, ${b}n${n}ew, ${b}p${n}ause, ${b}q${n}uit | No walls"); # set title weechat::buffer_set($buffer, "time_for_each_line", "0"); # no timestamps weechat::buffer_set($buffer, "display", 1); # switch to it weechat::buffer_set($buffer, "type", "free"); # free content weechat::buffer_set($buffer, "key_bind_meta2-A", "/snake -2"); # up weechat::buffer_set($buffer, "key_bind_meta2-B", "/snake +2"); # down weechat::buffer_set($buffer, "key_bind_meta2-D", "/snake -1"); # left weechat::buffer_set($buffer, "key_bind_meta2-C", "/snake +1"); # right weechat::buffer_set($buffer, "key_bind_n", "/snake new"); weechat::buffer_set($buffer, "key_bind_p", "/snake pause"); weechat::buffer_set($buffer, "key_bind_q", "/snake quit"); init_snake(); }elsif($_[2] eq "pause"){ # toggle pause if($pause){ $pause=0; hook(1); move(); redraw(); }elsif($hook){ $pause=1; weechat::buffer_clear($buffer); hook(0); weechat::print_y($buffer, 11, " " x 35 . "S n a k e"); weechat::print_y($buffer, 12, " " x 34 . "p a u s e d"); weechat::print_y($buffer, 14, " " x 31 . "Press p to resume"); return weechat::WEECHAT_RC_OK; } }elsif($_[2] eq "new"){ init_snake(); }elsif($_[2] eq "quit"){ weechat::buffer_close($buffer); }elsif($_[2] && $hook){ $dir=$_[2]; hook(1); move(); } return weechat::WEECHAT_RC_OK; } sub move { if($dir+$prevdir==0){ $dir=$prevdir; } # don't go backwards if($dir==1){ $c++; } # new head position elsif($dir==2){ $r++; } elsif($dir==-1){ $c--; } elsif($dir==-2){ $r--; } $r%=$rows+1; # edges $c%=$cols+1; if($table[$r][$c] eq $food){ # eat $score++; if($score==50){ $level="Cool!"; $speed*=0.95; } elsif($score==100){ $level="Awesome!"; $speed*=0.92; } elsif($score==120){ $level="OMG!"; $speed*=0.9; } elsif($score==150){ $level="OMG!! INSANE!!!"; $speed*=0.7; } weechat::print_y($buffer, $rows+3, " Score: $score $level"); for my $i (0..10000){ my $randr=rand($rows+1); my $randc=rand($cols+1); if($table[$randr][$randc] eq $empty){ # new food $table[$randr][$randc]=$food; print_line($randr); $speed*=0.993; # speed up if($speed<1){ $speed=1; } hook(1); last; } if($i==10000){ hook(0); $table[$r][$c]=$tail[0]; print_line($r); weechat::print_y($buffer, $rows+3, " Score: $score $level YOU WON THE GAME!"); return weechat::WEECHAT_RC_OK; } # not really necessary... } }else{ my ($remr,$remc)=(shift(@coords),shift(@coords)); $table[$remr][$remc]=$empty; # remove the last coordinates print_line($remr); if($table[$r][$c] ne $empty){ # die $table[$r][$c]=$dead; tail(); print_line($r, "You died :( Press n for new game"); hook(0); return weechat::WEECHAT_RC_OK; } } $table[$r][$c]=$head; # snake to new coordinates print_line($r); tail(); push(@coords, ($r,$c)); # push the new coordinates to @coords array $prevdir=$dir; }