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

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

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

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

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

  感觉原来的make_food算法不够好,修改如下:

sub make_food{
if(@snake < $full){
my @empty_points=();
foreach(..$#bg){
my $y=$_;
foreach(..$#{$bg[0]}){
push @empty_points,[$y,$_] if($bg[$y][$_] eq '.');
}
} # 找出所有空的坐标点,存入@empty_points数组
until($food){
my $num=int( rand( scalar(@empty_points) ) ); # 随机取出@empty_points下标
my ($y,$x)=@{ $empty_points[$num] }[,];
$bg[$y][$x]='O';
$food=;
}
}
}

  一个要解决的问题:无阻塞获取按键。通过度娘找到模块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=>,HEIGHT=>,DEBUG=>};
my @bg=();
my @snake=();
my ($score,$food,$speed,$alive)=(,,,); # 长度、食物、速度、存活
my $full=WIDTH*HEIGHT;
my %direct=( UP=>[-,],
DOWN=>[,],
LEFT=>[,-],
RIGHT=>[,], ); # 移动方向
my $head='RIGHT'; # 初始移动方向 &init;
while($alive){
$speed=($speed<)?(+int($score/)):; # 速度控制
if(@snake==$full){
print "congratulations!\n"; # 蛇占满游戏区时显示
}
else{
&move;
&check_head;
&show if $alive;
sleep (-$speed*0.1);
}
} sub init{
my $y=int(HEIGHT/);
@bg=map{my $x=$_;[map{$bg[$x][$_]='.'}..WIDTH-]}..HEIGHT-;
@{$bg[$y]}[,]=('#','@'); # 初始蛇身位置
@snake=( [$y,],[$y,], ); # 保存蛇身坐标
&make_food; # 产生食物
}
sub show{
system("cls");
print "your score : $score\n";
print "current speed : ",$speed,"\n\n";
print @$_,"\n" foreach(@bg);
}
sub move{
ReadMode ;
my ($key,$cur);
$key=ReadKey(-);
$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[][]+$direct{$cur}[],$snake[][]+$direct{$cur}[]];
}
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=;
}
}
}
}
sub check_head{
# 蛇身超出范围
if($snake[][] < || $snake[][] > HEIGHT-
|| $snake[][] < || $snake[][] > WIDTH-){
$alive=;
}
# 蛇吃到自己
if(@snake>){
foreach(..$#snake){
if($snake[][] == $snake[$_][] && $snake[][] == $snake[$_][]){
$alive=;
}
}
}
# 移动
if($bg[$snake[][]][$snake[][]] eq '.'){
$bg[$snake[][]][$snake[][]]='@';
}
# 吃到食物
if($bg[$snake[][]][$snake[][]] eq 'O'){
$bg[$snake[][]][$snake[][]]='@';
$score++;
$food=;
&make_food;
push @snake,[$snake[-][],$snake[-][]]; # 新的蛇身放在尾部
}
$bg[$snake[-][]][$snake[-][]]='.'; # 先清除尾巴显示
pop @snake; # 去掉尾巴
map{$bg[$snake[$_][]][$snake[$_][]]='#'}..$#snake; # 其他蛇身显示
}

  游戏界面:

  

Perl字符贪吃蛇的更多相关文章

  1. C字符贪吃蛇

    算法参照Perl字符贪吃蛇,源码: #include <stdio.h> #include <windows.h> #define WIDTH 12 // 宽 #define ...

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

    某天闲逛时看见一副动图: 真的是非常贪吃,各种拐弯各种吃,感觉十分有趣. 用Perl来实现自动吃满,蓄谋已久,之前的字符贪吃蛇.深度优先算法.A*算法,都是为此篇做铺垫. 那么,怎样让蛇不吃到自己呢? ...

  3. 字符界面的贪吃蛇--链表--C++

    前天看了下链表,由于平时对链表的使用不多,所以对链表的应用也没什么了解,所以想来想去,就想用链表实现一下贪吃蛇. 下面言归正传,先看效果图,再看代码,其他没有了! 图1: 图2: 代码: #inclu ...

  4. 基于AT89C51单片机的贪吃蛇电子游戏(仿真)

    有关贪吃蛇的历史发展可以看一下这个网址,贪吃蛇最初的设计和现在并不相同..http://www.techweb.com.cn/internet/2013-02-21/1278055.shtml 该项目 ...

  5. C语言之贪吃蛇

    利用链表的贪吃蛇,感觉自己写的时候还是有很多东西不熟悉, 1.预编译 2.很多关于系统的头文件也不是很熟悉 3.关于内存 第一个是.h头文件 #ifndef _SNAKE_H_H_H #define ...

  6. 【BZOJ-4213】贪吃蛇 有上下界的费用流

    4213: 贪吃蛇 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 58  Solved: 24[Submit][Status][Discuss] Desc ...

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

    C语言写贪吃蛇本来是打算去年暑假写的,结果因为ACM集训给耽搁了,因此借寒假的两天功夫写了这个贪吃蛇小项目,顺带把C语言重温了一次. 是发表博客的前一天开始写的,一共写了三个版本,第一天写了第一版,第 ...

  8. 多线程的Python 教程--“贪吃蛇”

    本指南的里代码可以在这里下载:  threadworms.py ,或者从  GitHub.代码需要  Python 3 或 Python 2 ,同时也需要安装  Pygame . 点击查看大版本图片 ...

  9. [010]转+修正---C++的贪吃蛇程序(未用面向对象封装)

    在网上看到一段贪吃蛇程序,自己心痒下了下来又稍微做了一点修改. 没有用面向对象的方式来进行封装,下次准备试试. 需要在windows环境下进行编译 #include<iostream> # ...

随机推荐

  1. thinkphp5中使用phpmailer实现发送邮件功能

    一.开启SMTP服务(使用php发送邮件需要用到SMTP服务,这里以163邮箱的SMTP服务为例). 1.登录163邮箱,在首页上找到“设置”. 2.选择开启的服务,一般都全选,POP3/SMTP/I ...

  2. 那些年伴我一起成长的SAP装备

    今天这篇文章无关技术,我们来聊聊SAP装备,即打上了SAP logo的那些物品. 但凡在SAP圈子工作过一段时间的从业者们,手上或多或少都拥有一些此类装备.Jerry当然也不例外,这些装备无论物品本身 ...

  3. kubernetes-使用Nginx配置ingress-controllers

    下载 Nginx Ingress Controller 配置文件: wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/ma ...

  4. 使用SikuliX定位Object(flash)元素

    先说一下背景,这个是我们测试的系统上的一个上传文件的地方,但是用传统的selenium方法很难定位的到.具体的样子是下面这样的. 使用id等属性定位做点击操作好像不能直接操作.无奈之下,只好从网上找找 ...

  5. Java synchronized实现原理总结和偏量锁、轻量锁、重量锁、自旋锁

    synchronized实现同步的基础:Java中的每一个对象都可以作为锁.具体表现为以下3种形式. 对于普通同步方法,锁是当前实例对象(this). 对于静态同步方法,锁是当前类的Class对象. ...

  6. selenium常用的API(二)浏览器窗口设置

    浏览器窗口最大化 # encoding=utf-8 from selenium import webdriver driver = webdriver.Ie(executable_path=" ...

  7. dt二次开发之-url伪静态的自定义

    dt内核的方便性在于代码内核完全开源,都可以根据自身需要进行优化整改,个人在这段时间的深入研究,发现这套内核的方便性,今天继续给大家分享下DT的url伪静态如何自定义函数. url自定义文件是在api ...

  8. maven 在执行package,install,deploy时使用clean与不使用clean的区别

    有时候用mvn install后,新改的内容不生效,一定要后来使用mvn clean install 才生效,由于之前没有做记录,以及记不清是什么情况下才会出现的问题,于是想看看clean和不clea ...

  9. 如何轻松愉快地理解条件随机场(CRF)

    https://blog.csdn.net/DCX_abc/article/details/78319246 机器学习之条件随机场(CRF): https://blog.csdn.net/wangya ...

  10. 2019-2020-1 20199302《Linux内核原理与分析》第三周作业

    云班课学习内容 一.C语言中嵌入汇编代码 1.内嵌汇编语法 (1)C语言中嵌入汇编代码的写法: asm( 汇编语句模板: 输出部分: 输入部分: 破坏描述部分): 说明:输出部分和输入部分对应着C语言 ...