Perl字符贪吃蛇
一时兴起,想试试能不能用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字符贪吃蛇的更多相关文章
- C字符贪吃蛇
算法参照Perl字符贪吃蛇,源码: #include <stdio.h> #include <windows.h> #define WIDTH 12 // 宽 #define ...
- Perl看完这个,再不敢说自己会玩贪吃蛇
某天闲逛时看见一副动图: 真的是非常贪吃,各种拐弯各种吃,感觉十分有趣. 用Perl来实现自动吃满,蓄谋已久,之前的字符贪吃蛇.深度优先算法.A*算法,都是为此篇做铺垫. 那么,怎样让蛇不吃到自己呢? ...
- 字符界面的贪吃蛇--链表--C++
前天看了下链表,由于平时对链表的使用不多,所以对链表的应用也没什么了解,所以想来想去,就想用链表实现一下贪吃蛇. 下面言归正传,先看效果图,再看代码,其他没有了! 图1: 图2: 代码: #inclu ...
- 基于AT89C51单片机的贪吃蛇电子游戏(仿真)
有关贪吃蛇的历史发展可以看一下这个网址,贪吃蛇最初的设计和现在并不相同..http://www.techweb.com.cn/internet/2013-02-21/1278055.shtml 该项目 ...
- C语言之贪吃蛇
利用链表的贪吃蛇,感觉自己写的时候还是有很多东西不熟悉, 1.预编译 2.很多关于系统的头文件也不是很熟悉 3.关于内存 第一个是.h头文件 #ifndef _SNAKE_H_H_H #define ...
- 【BZOJ-4213】贪吃蛇 有上下界的费用流
4213: 贪吃蛇 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 58 Solved: 24[Submit][Status][Discuss] Desc ...
- 小项目特供 贪吃蛇游戏(基于C语言)
C语言写贪吃蛇本来是打算去年暑假写的,结果因为ACM集训给耽搁了,因此借寒假的两天功夫写了这个贪吃蛇小项目,顺带把C语言重温了一次. 是发表博客的前一天开始写的,一共写了三个版本,第一天写了第一版,第 ...
- 多线程的Python 教程--“贪吃蛇”
本指南的里代码可以在这里下载: threadworms.py ,或者从 GitHub.代码需要 Python 3 或 Python 2 ,同时也需要安装 Pygame . 点击查看大版本图片 ...
- [010]转+修正---C++的贪吃蛇程序(未用面向对象封装)
在网上看到一段贪吃蛇程序,自己心痒下了下来又稍微做了一点修改. 没有用面向对象的方式来进行封装,下次准备试试. 需要在windows环境下进行编译 #include<iostream> # ...
随机推荐
- mysql 插入一个字段 id自增并设置为主键
案例 ALTER TABLE customer MODIFY COLUMN custID int NOT NULL AUTO_INCREMENT 开启: ALTER TABLE 表名 MODIFY C ...
- Arm存储器
Arm可以引出27根地址线,只能实现128MB的寻址,那么要如何实现1GB的寻址呢?答案就是使用nGCS片选线,nGCSx为低电平为选中相应的外接设备.一共八根片选线,也就是bank1,bank2-以 ...
- 搭建一个VUE项目
搭建环境 搭建node环境 下载 1.进入node.js官方网站下载页,点击下图中框出位置,进行下载即可,当前版本为8.9.4,下载网址为:https://nodejs.org/zh-cn/downl ...
- 关于linux的档案随笔
刚才在看鸟哥的linux的私房菜,然后看到的部分是关于linux的档案配置部分,之前就强调过,在linux中所有的一切都是以档案的形式存在的,不过不同的文件有一定的区别,linux中是有副档案这个说法 ...
- 3.XPath
使用XPath可以在不遍历xml文档的情况下选择具体节点. 转自https://www.cnblogs.com/vaevvaev/p/6928201.html XPath可以快速定位到Xml中的节点或 ...
- python 字符串操作list[::-1]的几种用法
1.list[-1],此时只有一个参数,作用是通过下标访问数据,-1是倒数第一个. 2.list[:-1],作用是返回从start_index = 0到end_index = -1的一串数据这里的li ...
- 项目中使用express,只是单纯项目中使用
安装express npm install express --save-dv 建议安装到dev依赖里面 安装body-parse npm install body-parser --save-dev ...
- test20190519 NOIP 模拟赛 3
序列 [问题描述] 作为一名火星人,你为了占领地球,需要想方设法使地球人失去信心.现在你获得了一项能力,控制今后 n 天的天气温度,对于第 i 天,你能将温度控制在[ai,bi]中任意一个数字, 你的 ...
- 配置jdk和环境变量
1.官网下载jdk1.8,默认安装即可 2.JAVE_HOME:jdk安装目录 path:C:;%JAVA_HOME%\bin; C:;%JAVA_HONE%\jre\bin;(当dos界面输入命令 ...
- 多线程实现的方式二实现Rannable
package thread; class Thread2 implements Runnable{ private String name; public Thread2(String name) ...