用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……[另外有了点体会]

软件和网站开发以及相关技术探讨
头像
Drdi
帖子: 257
注册时间: 2009-10-02 15:47

用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……[另外有了点体会]

#1

帖子 Drdi » 2011-03-08 14:09

其实发这个贴有两个目的

第一个就是让学perl的同学们指点指点,用了一个晚上写的 :em06

第二个就是有点迷茫,想脱离编程菜菜的境界

在学校的时候学过汇编 C 和java 都会一些 但全是入门 编一个稍稍复杂一点的东西就像挤牙膏 心有余而力不足 就像昨天晚上写这个游戏……

很痛苦 你们懂得

后来读了下perl 发现比我学过的语言容易多了 类型少 灵活 不用顾虑太多语法方面的东西 还很强大

于是想从perl深入下去 买了三本书 learning perl intermediate perl 和mastering perl 目前只看到小骆驼书的第十章

如果只是看书的话 看完一本之后会觉得很迷茫 不知道到底怎么运用 用在什么地方

这个时候应该是多读别人的好代码和自己多写代码的时候了吧

但是网上这样的perl代码似乎有点少啊 能不能推荐几个适合初学者的关于perl的网站呢?书也可以 就是可以让人多多写代码 多多练习和参考的

不学perl的也可以推荐一下自己的学习路线啊

学perl的前辈们分享下你们当初是怎么学好perl的吧




通常由两个人玩(这个是你和程序玩……),一方出数字,一方猜。出数字的人要想好一个没有重复数字的4位数,不能让猜的人知道。猜的人就可以开始猜。每猜一个数字,出数者就要根据这个数字给出几A几B,其中A前面的数字表示位置正确的数的个数,而B前的数字表示数字正确而位置不对的数的个数。

把代码复制到文件里 随便起个名字xxx
然后终端里perl xxx
或者chmod 755 xxx然后 ./xxx



代码: 全选

#!/usr/bin/perl -w

use strict;
use 5.010;

my ($answer,$guess,$rand,@bit,%count,%emptyhash);
my $num=7;
my $a=0;
my $b=0;

REPLAY:

for (1..4){											#这一段用来生成随机数
	$rand=int(rand(10));
	$count{$rand}++;
	redo if($count{$rand}>1);
}
# say keys %count;                                                                                              #调试或作弊用
say "Please enter a four-digit,the numbers are different for each bit.";

for (1..7){											#一共7次机会
	chomp ($guess=<STDIN>);

	while($guess=~/[\D]/){
		say "You entered an INCORRECT number,try again please.";
		chomp ($guess=<STDIN>);
	}

	@bit=keys %count;										 #这里是逐位比较
		if ($guess=~/$bit[0].../){									#应该有更好的办法吧 写的有点丑
			$a++;
		} elsif ($guess=~/.*$bit[0].*/){
			$b++;
		}

		if ($guess=~/.$bit[1]../){
			$a++;
		} elsif ($guess=~/.*$bit[1].*/){
			$b++;
		}

		if ($guess=~/..$bit[2]./){
			$a++;
		} elsif ($guess=~/.*$bit[2].*/){
			$b++;
		}

		if ($guess=~/...$bit[3]/){
			$a++;
		} elsif ($guess=~/.*$bit[3].*/){
			$b++;
		}


	if ($a==4){
		say "Congratulations!You guessed it.";
AGAIN:	print "Replay?(y/n)";
		if (($answer=<STDIN>) eq "y\n"){
			$a=0,$b=0,$answer=0,$rand=0,$num=7,@bit=(),%count=%emptyhash;		#各种数据初始化 hash不会 用{}和undef好像都不行
			goto REPLAY;
		} elsif ($answer eq "n\n"){
			exit 1;
		} else {
			say "Sorry,I don't know what you mean.";								#-_-b   本意是想弄成shell那样的 回答y/n之外的没有反应继续等待 
			say "Game exit...";												#但是不会 于是偷了个懒
			system "sleep 3";
			exit 1;
		}
	} else {
		if($num==1){
			say "Sorry,up to guess 7 times,you have no chance.";
			print "The right number is ";
			say @bit;
			goto AGAIN;
		}
		say "\n".$a."A".$b."B..........Try again.  ".--$num." opportunities left.\n";
		$a=0;
		$b=0;
	}
}
[/b][/size]



前一段时间学perl 主要是看中了perl的简洁强大 相比C和汇编 写相同的一个程序 代码量要少很多

现在想想自己是太急于搞出来一些作品了 反而忽略了写程序方面的一些内功

现在硬件发展很快 高级语言的低效率大部分时候都可以弥补了

虽然我学的高级语言不多 但就从perl来看 真的是越来越接近于人类语言了 特别是看了perl6的一些新特性之后

这样的语言越来越容易被学会 也许也会越来越多 更新的越来越快 如果没有学好计算机方面的内功 只是忙于去追赶更新更潮流的语言…… :em06

现在静下心开始看一些比较底层的东西了 等有所成 再好好学习perl

晒晒我看过的一些书吧 不怕高手见笑 主要是提供给和我水平差不多的童鞋 如果大家也有自己的好书千万不要藏着掖着 都拿来晒晒吧 :em02

汇编语言(第二版 王爽 清华大学出版社) 这本书看着非常之直白 循序渐进 差不多算是傻瓜入门书吧 内容很浅

我一开始看的 IBM-PC汇编语言程序设计 有点吃力就先看这本了 这本书还有一个汇编网http://www.asmedu.net/ 也很不错

C primer plus 作为C语言入门书也不错 看谭浩强的C 有些地方真的是写了好多 但就是让我不得要领 也许是当初我没底子吧 不过看他的书没一点代码风格的

这点很不好 另外还有 C和指针 这本也不错

还有就是现在在看的 深入理解计算机系统 第二版 以程序员的角度来写的 如果不知道书上的那些细节 很容易写出来漏洞多多 效率低下的程序

还有算法导论 我没有细看 听说是本好书 和上面那本书是一个系列的 算法也是很重要的 我还没来得及研究……这个可以上acm或者spoj实践实践


还有就是多谢 21楼 提供的一些书 英文好的同学可以看看
anticlockwise 写了: 光学语言本身是当然不够的,要学一门计算机语言一般就要从最基本的学起,比如算法+数据结构、数学~还要注意的就是代码规范,比如goto语句就不要用了,可以用函数/方法(Perl中用sub)来代替其中一些~Perl属于动态语言,自然有许多动态语言的特征,比如高阶函数,Closure,First Class Data Structure等等,这些都是需要去理解和活用的。如果这些都了解了,Perl看起书来很快的,如果只算Perl书籍,除了Learning Perl之外,我推荐Advanced Perl Programming, Perl Best Practices和Perl Hacks,都是Oreilly公司的~

其他的基础书籍有:Concrete Mathematics, Introduction to Algorithms, The Art of Computer Programming (Volumes 1-4), Algorithms in C/C++/Java (Parts 1-5), The Algorithm Design Manual, Modern Operating Systems, Compilers - Principles, Techniques and Tools

经常去做些算法题也是学习的一个好办法,比如上Topcoder, ACM的网站都可以
上次由 Drdi 在 2011-04-29 1:24,总共编辑 4 次。
爱Linux 也爱Ubuntu
简洁美观的桌面
更爱高效稳定的系统
不是不折腾难受夫斯基不想浪费时间
我和大多数人一样 我是菜菜
我要有菜菜的觉悟
我是Drdi
头像
daf3707
论坛版主
帖子: 12739
注册时间: 2007-06-13 15:57
来自: 在他乡

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#2

帖子 daf3707 » 2011-03-08 14:11

我围观也看不懂 :em01
头像
飞火流星
帖子: 990
注册时间: 2010-05-11 21:50

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#3

帖子 飞火流星 » 2011-03-08 14:21

哥,咱能说的在稍微稍微就稍微详细一点么??
完全不知道perl的还是很多人的啊。。。
怎么让他运行啊??
有事多折腾。。。没事瞎折腾。。。
本本
acer 4745g i5-430 4G ATI5650 1G 独显 500G硬盘
台台
赛扬coppermine 1.0GHz 160MB内存 集成显声卡 网卡一块。
archlinux+xfce无压力
头像
Drdi
帖子: 257
注册时间: 2009-10-02 15:47

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#4

帖子 Drdi » 2011-03-08 14:52

飞火流星 写了:哥,咱能说的在稍微稍微就稍微详细一点么??
完全不知道perl的还是很多人的啊。。。
怎么让他运行啊??

啊 不好意思 忘记了

就是小时候玩过的猜数字小游戏

把代码复制到文件里 随便起个名字 xxx

然后 perl xxx就行了

或者chmod 755 xxx 然后 ./xxx
爱Linux 也爱Ubuntu
简洁美观的桌面
更爱高效稳定的系统
不是不折腾难受夫斯基不想浪费时间
我和大多数人一样 我是菜菜
我要有菜菜的觉悟
我是Drdi
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#5

帖子 eexpress » 2011-03-08 15:49

say "\n".$a."A".$b."B..........Try again. ".--$num." opportunities left.\n";
@@@
内嵌变量,一样看得清楚嘛。
● 鸣学
头像
nmsfan
帖子: 18958
注册时间: 2009-10-16 22:46
来自: finland

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#6

帖子 nmsfan » 2011-03-08 16:12

果然出现了神的身影
看不懂的围观~~~~~
>>>>推Ubuntu 桌面培训~~<<<<
>>>>想加入/了解gimp汉化吗,点我吧~<<<<
——————————————————————
不推荐wubi,也不推荐你给别人推荐wubi…………
随心而为的感觉真好……
强推mayhem!!
强推ensiferum
头像
Drdi
帖子: 257
注册时间: 2009-10-02 15:47

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#7

帖子 Drdi » 2011-03-08 16:13

eexpress 写了:say "\n".$a."A".$b."B..........Try again. ".--$num." opportunities left.\n";
@@@
内嵌变量,一样看得清楚嘛。
say "\n${a}A${b}B..........Try again. ".--$num." opportunities left.\n";

看了下小骆驼 是这个意思吧

这样清晰一些 那个--$num不知道能不能进去

神啊……就知道你会来的

想当初我走上perl这条路 你也有一半功劳的 好像就是看到坛子里你写的perl……

能不能说说自己的学习方法呢?或者介绍一些学习perl的资源等等??
爱Linux 也爱Ubuntu
简洁美观的桌面
更爱高效稳定的系统
不是不折腾难受夫斯基不想浪费时间
我和大多数人一样 我是菜菜
我要有菜菜的觉悟
我是Drdi
头像
雨坤毅
帖子: 232
注册时间: 2010-08-28 14:34
系统: ArchLinux
联系:

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#8

帖子 雨坤毅 » 2011-03-08 17:21

偶是学Java的,现在还没学多少,这个游戏我也做过,呵呵,献丑了.... :em03

代码: 全选

import java.util.Scanner;

/**
 * 猜数字(又称 Bulls and Cows )是一种大概于20世纪中期兴起于英国的益智类小游戏。
 * 一般由两个人玩,也可以由一个人和电脑玩,在纸上、在网上都可以玩。 这种游戏规则简单,但可以考验人的严谨和耐心。 作者:张坤 日期:2010-01-12
 * 版本:1.0
 */
public class BAC {
	/**
	 * 输入对象
	 */
	private Scanner scan = new Scanner(System.in);
	/**
	 * 游戏等级(1-4)
	 */
	private int level = 1;
	/**
	 * 是否可重复
	 */
	private boolean isRepeat = false;

	/**
	 * 主方法
	 */
	public static void main(String[] args) {

		new BAC().enter();
	}

	/**
	 * 进入游戏,显示欢迎语句
	 */
	public void enter() {
		System.out.println("欢迎进入猜数字游戏!");
		try {
			Thread.sleep(1000);
		} catch (Exception e) {

		}
		menu();
	}

	/**
	 * 游戏菜单
	 */
	public void menu() {

		System.out.println("--------菜--单--------");
		System.out.println("\t1.开始");
		System.out.println("\t2.设置");
		System.out.println("\t3.帮助");
		System.out.print("请选择:");
		int sel = scan.nextInt();
		switch (sel) {
		case 1:
			startGame();// 开始游戏
			break;
		case 2:
			option();// 设置
			break;
		case 3:
			help();// 帮助
			menu();
			break;
		default:

			menu();
		}
	}

	/**
	 * 设置游戏等级
	 */
	private void setGameLevel() {

		System.out.println("--------游戏等级--------");
		System.out.println("\t1." + getLevelStr(1));
		System.out.println("\t2." + getLevelStr(2));
		System.out.println("\t3." + getLevelStr(3));
		System.out.println("\t4." + getLevelStr(4));
		System.out.println("\t5.返回上级菜单");
		System.out.print("请选择:");
		int sel = scan.nextInt();
		switch (sel) {
		case 1:
			level = 1;
			break;
		case 2:
			level = 2;
			break;
		case 3:
			level = 3;
			break;
		case 4:
			level = 4;
			break;
		case 5:
			option();
			break;
		default:
			setGameLevel();
			return;
		}
		System.out.println("设置成功!");
		try {
			Thread.sleep(1000);
		} catch (Exception e) {

		}
		setGameLevel();
	}

	/**
	 * 设置游戏
	 */
	private void option() {

		System.out.println("--------设--置--------");
		System.out.println("\t1.设置等级");
		System.out.println("\t2.难度设置");
		System.out.println("\t3.返回主菜单");
		System.out.print("请选择:");
		int sel = scan.nextInt();
		switch (sel) {
		case 1:
			setGameLevel();// 设置游戏等级
			break;
		case 2:
			setRepead();// 设置
			break;
		case 3:
			menu();// 帮助
			return;
		default:
			option();
			return;
		}
	}

	private void help() {
		String h = "由电脑根据游戏设置产生一个数," + "每猜一个数字,电脑就根据这个数字给出几A几B,"
				+ "其中A前面的数字表示位置正确的数的个数," + "而B前的数字表示数字正确而位置不对的数的个数。"
				+ "如规则为不重复等级4的正确答案为5234" + "而猜的人猜 5346,则是 1A2B,"
				+ "其中有一个5的位置对了," + "记为1A,而3和4这两个数字对了,"
				+ "而位置没对,因此记为 2B,合起来就是 1A2B。" + "接着猜的人再根据出题者的几A几B继续猜,"
				+ "直到猜中(即 4A0B)为止。\n" + "输入任意字符回车继续";
		System.out.println(h);
		scan.next();
	}

	private void setRepead() {

		System.out.println("--------游戏难度--------");
		System.out.println("\t1.数字重复");
		System.out.println("\t2.数字不重复");
		System.out.println("\t3.返回上级菜单");
		System.out.print("请选择:");
		int sel = scan.nextInt();
		switch (sel) {
		case 1:
			isRepeat = true;
			break;
		case 2:
			isRepeat = false;
			break;
		case 3:
			option();
			return;
		default:
			setRepead();
			return;
		}
		System.out.println("设置成功!");
		try {
			Thread.sleep(1000);
		} catch (Exception e) {

		}
		setRepead();
	}

	private String getLevelStr(int i) {
		switch (i) {
		case 1:
			return "★☆☆☆";
		case 2:
			return "★★☆☆";
		case 3:
			return "★★★☆";
		case 4:
			return "★★★★";
		}
		return "";
	}

	/**
	 * 根据玩家的设置输出提示信息
	 */
	private void printMsg() {
		System.out.println("\n当前游戏等级为" + getLevelStr(level));
		System.out.println("您可以输入" + level + "位" + (isRepeat ? "可以" : "不可")
				+ "重复的数字");
		System.out.println("您共有" + getInputTime() + "次机会来猜对这个数");
	}

	/**
	 * 根据玩家的设置产生数字
	 */
	private String getGameNum() {
		int result = 0;
		String ret = "";
		switch (level) {
		case 1:
			result = (int) (Math.random() * 10);
			ret = "" + result;
			break;
		case 2:
			do {
				result = (int) (Math.random() * 100);
				ret = (result < 10 ? "0" : "") + result;
			} while (!(checkAccept(ret, 2)));
			break;
		case 3:
			do {
				result = (int) (Math.random() * 1000);
				ret = (result < 100 ? "0" : "") + result;
			} while (!(checkAccept(ret, 3)));
			break;
		case 4:
			do {
				result = (int) (Math.random() * 10000);
				ret = (result < 1000 ? "0" : "") + result;
			} while (!(checkAccept(ret, 4)));
			break;
		}
		return ret;
	}

	/**
	 * 根据设置返回可以输入的次数
	 */
	private int getInputTime() {
		if (!isRepeat) {
			switch (level) {
			case 1:
				return 3;
			case 2:
				return 5;
			case 3:
				return 7;
			case 4:
				return 9;
			}
		} else {
			switch (level) {
			case 1:
				return 3;
			case 2:
				return 8;
			case 3:
				return 16;
			case 4:
				return 20;
			}
		}
		return 0;
	}

	/**
	 * 根据输入的内容判定结果,返回如1A2B形式
	 */
	private String judge(String real, String accept) {
		if (!isRepeat) {
			int a = 0;
			int b = 0;
			for (int i = 0; i < level; i++) {
				String t = real.substring(i, i + 1);
				String p = accept.substring(i, i + 1);
				if (t.equals(p)) {
					a++;
				} else {
					if (real.indexOf(p) != -1)
						b++;
				}
			}
			return a + "A" + b + "B";
		} else
			return level + "A0B";
	}

	/**
	 * 根据判定字符串判定是否猜对了
	 */
	private boolean isWin(String judgeStr) {
		if ((level + "A0B").equals(judgeStr))
			return true;
		return false;
	}

	/**
	 * 验证输入的数是否合法
	 */
	private boolean checkAccept(String str, int level) {
		if (!str.matches("^\\d{" + level + "}$"))
			return false;
		if (!isRepeat) {
			if (str.length() == level) {
				for (int i = 0; i < level - 1; i++) {
					if (str.indexOf(str.substring(i, i + 1), i + 1) != -1)
						return false;
				}
				return true;
			} else
				return false;
		} else {
			if (str.length() == level)
				return true;
			else
				return false;
		}
	}

	/**
	 * 开始游戏,该方法控制游戏的主流程
	 */
	private void startGame() {

		System.out.print("系统准备中");
		for (int i = 0; i < 3; i++)
			try {
				Thread.sleep(1000);
				System.out.print("..");
			} catch (Exception e) {

			}
		String realStr = "";
		realStr = getGameNum();
		boolean isSucceed = false;
		int useTime = 0;
		String accept;
		String judgeStr;
		printMsg();
		for (int i = 1, s = getInputTime(); i <= s; i++) {
			System.out.print("请输入您猜的数:");
			accept = scan.next();
			if (checkAccept(accept, level)) {
				judgeStr = judge(realStr, accept);
				System.out.println("结果:" + judgeStr);
				if (isWin(judgeStr)) {
					isSucceed = true;
					useTime = i;
					break;
				}
			} else {
				System.out.println("您输入的格式错误,本次不计数!");
				i--;
			}
		}
		if (isSucceed) {
			System.out.println("恭喜您仅用了" + useTime + "次就猜对了!");
		} else {
			System.out.println("对不起,游戏失败,您在规定的次数内还未猜中!正确答案为:" + realStr);
		}
		System.out.print("输入y在来一盘,否则返回主菜单:");
		if ("y".equals(scan.next())) {
			startGame();
		} else
			menu();
	}
}
附件
选区_012.png
选区_011.png
选区_009.png
选区_008.png
zhangkun.tar.gz
解压后有源文件和编译好的Class文件,源文件是GBK编码...直接用java BAC命令执行...
(6.76 KiB) 已下载 146 次
---------------------------------------
http://yky.me
---------------------------------------
头像
Drdi
帖子: 257
注册时间: 2009-10-02 15:47

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#9

帖子 Drdi » 2011-03-08 17:33

ls的程序写的很精致啊

还能选择难度的 我这是抛砖引玉了 还好能看懂些java

程序都是相通的 :em01
爱Linux 也爱Ubuntu
简洁美观的桌面
更爱高效稳定的系统
不是不折腾难受夫斯基不想浪费时间
我和大多数人一样 我是菜菜
我要有菜菜的觉悟
我是Drdi
头像
雨坤毅
帖子: 232
注册时间: 2010-08-28 14:34
系统: ArchLinux
联系:

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#10

帖子 雨坤毅 » 2011-03-08 17:48

呵呵...我现在在写俄罗斯方块...实在找不到事做,学校学的进度太慢...又不想和同学打游戏,总想写点东西来提高水平......还搞了一阵子Qt..... :em01
附件
选区_013.png
---------------------------------------
http://yky.me
---------------------------------------
头像
月下叹逍遥
论坛版主
帖子: 33994
注册时间: 2010-10-07 14:23
系统: Archdows10
来自: 某系某星某洲某国某省某市
联系:

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#11

帖子 月下叹逍遥 » 2011-03-08 18:07

nmsfan 写了: 看不懂的围观~~~~~
浮生七十今三十,从此凄惶未可知
头像
Drdi
帖子: 257
注册时间: 2009-10-02 15:47

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#13

帖子 Drdi » 2011-03-08 19:30

tenzu 写了:perl乃神器

:em70

xxx说过:能力越大 责任也就越大……

因此 我认为神有责任将神器凡间化 :em70

可是神只留下了一个背影 :em80

其实我主要是想听听学perl的前辈们的学习经验和方法的 最好介绍一些学习资源

神未能领悟我等凡人的意图 :em79
爱Linux 也爱Ubuntu
简洁美观的桌面
更爱高效稳定的系统
不是不折腾难受夫斯基不想浪费时间
我和大多数人一样 我是菜菜
我要有菜菜的觉悟
我是Drdi
头像
HelloAndroid
帖子: 156
注册时间: 2010-10-17 18:23

Re: 用perl写了一个小游戏 欢迎各种围观、吐槽、莅临指导……

#14

帖子 HelloAndroid » 2011-03-08 21:09

我觉得那个写俄罗斯方块的就是个好同学啊!我也写过俄罗斯方块,用java,蛮好玩的,想写个连连看! :em01
用起来还是蛮舒服的!
生命在于折腾!
为什么这个论坛复旦的人很少!!
回复