Perl字符贪吃蛇

  一时兴起,想试试能不能用perl实现字符贪吃蛇,算法如下:

  定义2个数组@bg、@snake,@bg用来显示整个界面,@snake从蛇头开始保存蛇的坐标点。

  蛇每移动一次,新的坐标点放到@snake头部,并去除最后一个元素,再改变@bg对应坐标的值。

  通过控制台窗口不断清屏再打印,使蛇“看起来在移动”。

  简单的速度控制实现:每次移动后sleep 若干秒。

  一个要解决的问题:无阻塞获取按键。通过度娘找到模块Term::ReadKey,新的问题产生了:批量输入方向,蛇会依次按照输入移动,暂时想不到好办法解决。

  使用Time::HiRes的sleep,实现毫秒级等待,use 5.01 支持given...when语法。

  使用 w a s d 控制移动,代码如下:

use strict;
use 5.01;
use Time::HiRes qw/sleep/;
use Term::ReadKey;
use constant {WIDTH=>10,HEIGHT=>6,DEBUG=>1};
my @bg=();
my @snake=();
my ($score,$food,$speed,$alive)=(0,0,1,1); # 长度、食物、速度、存活
my $full=WIDTH*HEIGHT;
my %direct=( UP=>[-1,0],
            DOWN=>[1,0],
            LEFT=>[0,-1],
            RIGHT=>[0,1], ); # 移动方向
my $head=‘RIGHT‘; # 初始移动方向

&init;
while($alive){
    $speed=($speed<9)?(1+int($score/10)):9;  # 速度控制
    if(@snake==$full){
        print "congratulations!\n";  # 蛇占满游戏区时显示
    }
    else{
        &move;
        &check_head;
        &show if $alive;
        sleep (1-$speed*0.1);
    }
}

sub init{
    my $y=int(HEIGHT/2);
    @bg=map{my $x=$_;[map{$bg[$x][$_]=‘.‘}0..WIDTH-1]}0..HEIGHT-1;
    @{$bg[$y]}[1,2]=(‘#‘,‘@‘); # 初始蛇身位置
    @snake=( [$y,2],[$y,1], ); # 保存蛇身坐标
    &make_food;  # 产生食物
}
sub show{
    system("cls");
    print "your score : $score\n";
    print "current speed : ",$speed,"\n\n";
    print @$_,"\n" foreach(@bg);
}
sub move{
    ReadMode 2;
    my ($key,$cur);
    $key=ReadKey(-1);
    $key=~tr/a-z/A-Z/ if $key;
    given($key){
        # 不允许反向移动
        when(‘W‘){
            if($head eq ‘DOWN‘){
                $cur=‘DOWN‘;
            }
            else{
                $cur=$head=‘UP‘;
            }
        }
        when(‘A‘){
            if($head eq ‘RIGHT‘){
                $cur=‘RIGHT‘;
            }
            else{
                $cur=$head=‘LEFT‘;
            }
        }
        when(‘S‘){
            if($head eq ‘UP‘){
                $cur=‘UP‘;
            }
            else{
                $cur=$head=‘DOWN‘;
            }
        }
        when(‘D‘){
            if($head eq ‘LEFT‘){
                $cur=‘LEFT‘;
            }
            else{
                $cur=$head=‘RIGHT‘;
            }
        }
        default { $cur=$head; }
    }
    unshift @snake,[$snake[0][0]+$direct{$cur}[0],$snake[0][1]+$direct{$cur}[1]];
}
sub make_food{
    if(@snake < $full){
        until($food){
            my ($x,$y)=(int(rand(WIDTH)),int(rand(HEIGHT)));
            if($bg[$y][$x] eq ‘.‘){
                $bg[$y][$x]=‘O‘;
                $food=1;
            }
        }
    }
}
sub check_head{
    # 蛇身超出范围
    if($snake[0][0] < 0 || $snake[0][0] > HEIGHT-1
        || $snake[0][1] < 0 || $snake[0][1] > WIDTH-1){
            $alive=0;
    }
    # 蛇吃到自己
    if(@snake>3){
        foreach(1..$#snake){
            if($snake[0][0] == $snake[$_][0] &&  $snake[0][1] == $snake[$_][1]){
                $alive=0;
            }
        }
    }
    # 移动
    if($bg[$snake[0][0]][$snake[0][1]] eq ‘.‘){
        $bg[$snake[0][0]][$snake[0][1]]=‘@‘;
    }
    # 吃到食物
    if($bg[$snake[0][0]][$snake[0][1]] eq ‘O‘){
        $bg[$snake[0][0]][$snake[0][1]]=‘@‘;
        $score++;
        $food=0;
        &make_food;
        push @snake,[$snake[-1][0],$snake[-1][1]];  # 新的蛇身放在尾部
    }
    $bg[$snake[-1][0]][$snake[-1][1]]=‘.‘;  # 先清除尾巴显示
    pop @snake;  # 去掉尾巴
    map{$bg[$snake[$_][0]][$snake[$_][1]]=‘#‘}1..$#snake;  # 其他蛇身显示
}

  游戏界面:

  

时间: 2024-11-09 03:03:15

Perl字符贪吃蛇的相关文章

Perl看完这个,再不敢说自己会玩贪吃蛇

某天闲逛时看见一副动图: 真的是非常贪吃,各种拐弯各种吃,感觉十分有趣. 用Perl来实现自动吃满,蓄谋已久,之前的字符贪吃蛇.深度优先算法.A*算法,都是为此篇做铺垫. 那么,怎样让蛇不吃到自己呢? 1.让蛇按照我们设计好的路线行进,在一个N*M(N.M均为偶数,奇数不讨论)的游戏区域,设计好路线如下: 当花儿谢了,果子熟透,春夏秋冬一个轮回后,蛇终于吃满了... 2.假设蛇总是追着自己的尾巴跑,那么永远不会死:然而,这没什么鸟用,我们需要的是一条“贪吃”的蛇. 3.在2上稍稍改进,吃完食物后

C《贪吃蛇》简易字符版

哇咔咔,这是我步入游戏制作界的第一步. 忙活了一个国庆,虽说bug略多,但是成就感满满的. #include<stdio.h> #include<stdlib.h> #include<Windows.h> #define H 20 #define L 20 void map(int hard); void maphard(void); void play(void); void food(void); int live(void); void direction(cha

游戏开发(一)——控制台 贪吃蛇

贪吃蛇游戏设计中主要需要注意的几点: 1:坐标的定义:定义为左上角为(0,0),向右为x正方向,向下为y正方向 2:蛇的设计, 蛇身:m_body,这里用的是链表(是之前写好的双链表),一个节点就是蛇身的一节 每节蛇身的属性包括x,y坐标:column_x,row_y,x表示在地图上的第几列,y表示在地图上的第几行 蛇有一个属性叫朝向,也就是当前在往上.下.左.右的哪个方向移动:m_forward 蛇的动作有:Turn,转向.转向有个判断,就是不能向相反的方向转,比如本来向上运动,按向下键,是无

命令贪吃蛇2_0

命令贪吃蛇2_0 游戏规则 吃食物变长,撞到墙里或咬到自己死亡,占满全屏算赢. 代码 运行前先把输入法调至英文!(我因为没调在测试时死了无数次) http://www.cnblogs.com/cbattle/p/6383867.html 过程 看了大佬推荐的博客( http://blog.sina.com.cn/s/articlelist_2233904382_0_1.html ),通过移动光标插入字符解决了频繁闪烁的问题. Console.SetCursorPosition(2 * y, x)

Pascal小游戏 贪吃蛇

一段未完成的Pascal贪吃蛇 说这段代码未完成其实是没有源代码格式化,FP中一行最多只有255字符宽. uses crt; const screenwidth=50; screenheight=24; wallchar='#'; snakechar='*'; ; type point=record x,y:integer; end; var snake:array [0..500] of point; map:array [0..screenwidth,0..screenheight] of

JavaScript实现简单贪吃蛇小游戏

之前上Web课,学到JavaScript的时候,老师要求写几个静态页面,要用到JavaScript.想了想就写个贪吃蛇吧.其实之前用pygame写过一次GUI的贪吃蛇,素材都是自己拿画图画的,其丑无比.所以这次还是老老实实用字符吧. 首先,是一些全局变量的定义: 1 <script> 2 var state = 0;//0 wait 1 run 2 over 3 var width = 40; 4 var height = 25; 5 var update = false; 6 var dir

贪吃蛇1.0&amp;&amp;贪吃蛇2.0

1 // 2 //main.c 3 //snake 4 // 5 //Created by Yubei Xiao on 12-12-16 6 //Copyright (c) 2015年 Sun Yat-sen University.All rights reserved. 7 // 8 9 #include<stdio.h> 10 #include<stdlib.h> 11 #include<time.h> 12 13 #define SNAKE_MAX_LENGTH

小项目特供 贪吃蛇游戏(基于C语言)

C语言写贪吃蛇本来是打算去年暑假写的,结果因为ACM集训给耽搁了,因此借寒假的两天功夫写了这个贪吃蛇小项目,顺带把C语言重温了一次. 是发表博客的前一天开始写的,一共写了三个版本,第一天写了第一版,第二天写了第二版和第三版. 相信C语言写个小游戏或小项目是大多数计算机相关专业的学生都做的事情,但是作为一个数学专业的学生,我们教研室的老师对C语言的要求也就比较低了,大一没有让我们做个小项目实践一次.至今为止用C/C++做过的三个小项目(大作业),一个是外校同学让我帮忙写的学生信息管理系统(天呐,这

Linux Curses编程实现贪吃蛇

curses库 简单而言,提供UNIX中多种终端 操作光标和显示字符 的接口.我们常见的vi就是使用curses实现的.现在一般都用ncurses库. Linux下curses函数库    Linux curses库使用      这两篇文章很详细地介绍了curses,在此就不重复了. ubuntu安装curses函数库 >sudo apt-get install ncurses-dev 用curses库,编译程序: gcc program.c -o program -lcurses 2.工作原