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> # ...
随机推荐
- jenkins rpm卸载
rpm卸载 1.rpm -e jenkins rpm -ql jenkins 检查是否卸载成功 2.彻底删除残留文件:find / -iname jenkins | xargs -n 1000 rm ...
- laravel使用withCount获取列表下关联模型的数量
模型里面 <?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model ...
- wget下载出现错误 403:Forbidden
在我尝试wget下载一张图片的时候,出现了如下错误: wget "https://k4b8k3x5.ssl.hwcdn.net/content/140516/1622-saaya-irie- ...
- VMware安装ubantu
下载ubantu镜像文件: http://mirror.pnl.gov/releases/xenial/ http://mirrors.melbourne.co.uk/ubuntu-releases/ ...
- 移动魔百和PTV-8098可以免拆直接安装第三方的软件
前言:江苏用户的福音啊!当地移动魔百和PTV-8098可以免拆直接安装第三方的软件,其他地区的PTV-8098未做测试,可以自己根据教程步骤进行测试: 准备工具:8G或4G的U盘(太大无法识别).电脑 ...
- VBS 自动发消息给对方
http://www.vbsedit.com/ Dim Name,Msg Name= "我家丫头" Msg = "333" set ws=wscript.cre ...
- MQ的常见应用场景
MQ的常见的应用场景为:解耦,异步,流量削峰 在解耦场景中: 不使用MQ的耦合场景: 使用解耦的场景为: 异步的方式: 不使用MQ的同步高延时请求场景: 使用异步化之后的接口性能优化: 没有使用mq的 ...
- 0029redis单机版环境搭建
linux环境下安装单机版redis,主要分为如下几步: 1. 安装gcc 2.下载安装包 3.解压安装包 4.进入解压目录并执行make和make install命令 5.查看默认安装目录 6.更改 ...
- 神经网络(9)--如何求参数: backpropagation algorithm(反向传播算法)
Backpropagation algorithm(反向传播算法) Θij(l) is a real number. Forward propagation 上图是给出一个training examp ...
- 接口测试工具soapUI
一.下载 官网:https://www.soapui.org/ 链接:https://pan.baidu.com/s/15LITTKIvfIoAq5IBpID8gA 提取码:l7p6 二.SoapUI ...