flashbang
[新米敲门贴][Java小游戏-炸弹人]
展开Biu

本帖最后由 flashbang 于 2013-2-9 12:40 编辑

#15t大家好, 这里是新米程序猿小轮回.

#23t说是新人其实我马上都要毕业了, 刚去三星实习2个月觉得工作太无聊撤退回家赋闲。

不扯了,上见面礼。

如题,是一个炸弹人累死的小游戏。初版大约用了3天,第一个可运行jar是一周左右,然后就天天在机房跟同学一起玩儿233。

本来是有局域网对战的,起初设定是支持4人对战,然后就,坑了。然后就懒得再做了。然后就没了

图1:主界面,有3个地图来着?忘了懒得去看,联网模块已经关掉了,因为性能太差。以后再说~

图2:改键,其实也没啥可改的,P1和P2的上下左右还有放雷。

图3:玩儿的部分...好吧, 我美术老师死得早,画面粗糙见谅。(或者说根本就是猎奇!?)

本体附件(我也不确定能不能传上来, jre无)

:【http://pan.baidu.com/share/link?shareid=314010&uk=671539592

就是这么个小游戏啦,炸弹人也没什么可介绍的。新人拜区,欢迎各位大大指教。以上。

[查看全文]
renoseven
俄罗斯方块
展开Biu

本帖最后由 renoseven 于 2013-5-7 13:54 编辑

很早之前学Java的时候写的俄罗斯方块 放上来与大家分享

界面是自己画的 然后声音借用了QQ游戏里面的

没什么技术含量 现在看也有很多需要改进的地方

PS:现在看代码已经惨不忍睹了,所以请轻喷

[查看全文]
lauyukit
刚学链表写的贪吃蛇=v=适合新手看
展开Biu

本帖最后由 Whisper1166 于 2012-12-21 12:59 编辑

[mw_shl_code=cpp,true]

#include "stdio.h"

#include "windows.h"

#include "conio.h"

#include "stdlib.h"

#include "time.h"

#include "string.h"

//因为我也是新手,真的,才学C语言一学期不到..所以没有高手写的那么难懂...目前在写printf写得跟狗一样...

//想必在大神面前这些结构体就像蓝天白云一样清晰明了

struct Snake //谁知道这些都是什么意思? (知道的去死!!!)

{ //蛇的结构体,xy是蛇身体的某一部分的坐标,*next是链表里的指针..

int x;

int y;

char body;

struct Snake *next;

}*front,*rear,*p,*q;

struct food//这是禁果(喂)的坐标

{

int x;

int y;

}a;

int main()

{

int i,j,score=0,time=10000,flag;//i j是对二维数组赋值和输出用的,time是画面停滞时间,flag是判断是否需要生成禁果(你够了)

char c,dir,Amatrix[30][80],name[15],love[]={"XXX"};//c是获取键盘输入,dir表示蛇移动方向,name只是game over以后记录名字用的 XXX我屏蔽掉了

loop:front=(struct Snake*)malloc(sizeof(struct Snake));//就是动态分配内存,通过指针front和rear指向蛇头和蛇尾

rear=(struct Snake*)malloc(sizeof(struct Snake));

front->body='H';//蛇头是H,蛇尾是X ←这是老师要求的

rear->body='X';

front->x=1,front->y=2;//设定初始蛇头蛇尾的坐标

rear->x=1,rear->y=1;

front->next=rear;

rear->next=NULL;//当然链表的末端的指针要清空

flag=0;

for(i=0;i<24;i++)

{

for(j=0;j<70;j++)

Amatrix[j]=' ';//先让二维数组全为空格

}

for(i=0,j=0;i<24;j++)

{

Amatrix[j]='-';

if(70==j)

{

j=0;i+=23;

}

}

for(i=0;i<24;i++)

Amatrix[70]='\0';

for(i=1;i<23;i++){

Amatrix[0]='|';Amatrix[69]='|';}//画框框

Amatrix[10][30]='o';

Amatrix[front->x][front->y]=front->body;//把对应位置的蛇身体的部分赋值给数组

Amatrix[rear->x][rear->y]=rear->body;// 这样后面输出二维数组就能表现出蛇的移动了

for(i=0;i<24;i++)

puts(Amatrix);//因为printf比较复杂,输出数组的时候快闪瞎我狗眼了,所以用puts

printf("↑=w,↓=s,←=a,→=d不能穿墙,吃自己或者走反方向必死,界面渣勿喷");

while(1)

{

c=getch();//dir跟c其实是一个意思,都是从键盘上读取输入,获取蛇的移动方向

dir=c;

if(('w'==dir)&&(Amatrix[front->x-1][front->y]!='-')&&(Amatrix[front->x-1][front->y]!='X'))//如果蛇没撞墙或者吃到自己

{

if(Amatrix[front->x-1][front->y]=='o')//吃到禁果,就创造新结点,让它的所有值等于蛇头,并把蛇头移位,蛇头的指针指向新结点

{ //蛇尾不变,这样蛇就变长了

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->x--;

Sleep(30); //保持竖直方向的速度与水平方向的速度平衡

score++;

flag=1;

}

else

{ //没吃禁果,同样创造新结点重复上面步骤,但是要把蛇尾去掉,这样蛇就不会变长

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->x--;

Sleep(30);

for(p=front;p!=rear;q=p,p=p->next);//让p指向rear,q指向rear前的一个结点

Amatrix[p->x][p->y]=' ';//把原来尾部的位置变成空格

free(p); //销毁尾部

rear=q; //尾部前移

q->next=NULL; //清空指针

p=q=NULL; //下面其他方向的就雷同了,其实能把重复的部分写成一个函数,看起来也简单点,不过撸主懒..

}

}

else if(('s'==dir)&&(Amatrix[front->x+1][front->y]!='-')&&(Amatrix[front->x+1][front->y]!='X'))

{

if(Amatrix[front->x+1][front->y]=='o')

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->x++;

Sleep(30);

score++;

flag=1;

}

else

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->x++;

Sleep(30);

for(p=front;p!=rear;q=p,p=p->next);

Amatrix[p->x][p->y]=' ';

free(p);

rear=q;

q->next=NULL;

p=q=NULL;

}

}

else if(('a'==dir)&&(Amatrix[front->x][front->y-1]!='|')&&(Amatrix[front->x][front->y-1]!='X'))

{

if(Amatrix[front->x][front->y-1]=='o')

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->y--;

score++;

flag=1;

}

else

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->y--;

for(p=front;p!=rear;q=p,p=p->next);

Amatrix[p->x][p->y]=' ';

free(p);

rear=q;

q->next=NULL;

p=q=NULL;

}

}

else if(('d'==dir)&&(Amatrix[front->x][front->y+1]!='|')&&(Amatrix[front->x][front->y+1]!='X'))

{

if(Amatrix[front->x][front->y+1]=='o')

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->y++;

score++;

flag=1;

}

else

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->y++;

for(p=front;p!=rear;q=p,p=p->next);

Amatrix[p->x][p->y]=' ';

free(p);

rear=q;

q->next=NULL;

p=q=NULL;

}

}

else if(((dir=='d')&&(Amatrix[front->x][front->y+1]=='|')||(Amatrix[front->x][front->y+1]=='X'))||((dir=='a')&&(Amatrix[front->x][front->y-1]=='|')||(Amatrix[front->x][front->y-1]=='X'))||((dir=='s')&&(Amatrix[front->x+1][front->y]=='-')||(Amatrix[front->x+1][front->y]=='X'))||((dir=='w')&&(Amatrix[front->x-1][front->y]=='-')||(Amatrix[front->x-1][front->y]=='X')))

{//撞墙或者吃到自己就死

system("cls");//清屏

printf("******************************************************************************\n");

printf("* *\n");

printf("* *\n");

printf("* *\n");

printf("* GAME OVER *\n");

printf("* *\n");

printf("* *\n");

printf("******************************************************************************\n");

printf(" Your score is %d \n",score);

printf(" 屌丝梦工厂出品 (ˉ﹃ˉ) copyright by Frost.\n");

printf("请输入你的名字:");

scanf("%s",name);

if(strcmp(name,love)==0)

printf(" 我喜欢你。 \n");//这是我给女神的末日表白,虽然她没玩这游戏就是了

else

printf("%s ,战斗力只有5的孩子呀你威武雄壮!!(`_ ′)ゝ 5s后重开\n",name);

if(score>=20)

printf("话说你是开挂的吧?\n");

Sleep(5000);//game over 五秒后重开

goto loop;//跳到开头重新游戏

}

for(p=front;p!=NULL;p=p->next)

Amatrix[p->x][p->y]=p->body;//把蛇对应位置的部分赋值给数组

if(flag==1)//如果已经吃了禁果就得重新生成一个

{

a.x=rand()%20+1;//保证禁果不越界 随机生成禁果的坐标

a.y=rand()%65+1;

if((a.x==0)||(Amatrix[a.x][a.y]=='X')||(Amatrix[a.x][a.y]=='H'))

a.x=10;

if((a.y==0)||(Amatrix[a.x][a.y]=='X')||(Amatrix[a.x][a.y]=='H'))

a.y=30;

Amatrix[a.x][a.y]='o';

flag=0;

}

while(!kbhit())//如果没有输入,就按之前移动的方向继续前进

{

Sleep(50);

if(('w'==dir)&&(Amatrix[front->x-1][front->y]!='-')&&(Amatrix[front->x-1][front->y]!='X'))

{

if(Amatrix[front->x-1][front->y]=='o')

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->x--;

Sleep(30);

score++;

flag=1;

}

else

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->x--;

Sleep(30);

for(p=front;p!=rear;q=p,p=p->next);

Amatrix[p->x][p->y]=' ';

free(p);

rear=q;

q->next=NULL;

p=q=NULL;

}

}

else if(('s'==dir)&&(Amatrix[front->x+1][front->y]!='-')&&(Amatrix[front->x+1][front->y]!='X'))

{

if(Amatrix[front->x+1][front->y]=='o')

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->x++;

Sleep(30);

score++;

flag=1;

}

else

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->x++;

Sleep(30);

for(p=front;p!=rear;q=p,p=p->next);

Amatrix[p->x][p->y]=' ';

free(p);

rear=q;

q->next=NULL;

p=q=NULL;

}

}

else if(('a'==dir)&&(Amatrix[front->x][front->y-1]!='|')&&(Amatrix[front->x][front->y-1]!='X'))

{

if(Amatrix[front->x][front->y-1]=='o')

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->y--;

score++;

flag=1;

}

else

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->y--;

for(p=front;p!=rear;q=p,p=p->next);

Amatrix[p->x][p->y]=' ';

free(p);

rear=q;

q->next=NULL;

p=q=NULL;

}

}

else if(('d'==dir)&&(Amatrix[front->x][front->y+1]!='|')&&(Amatrix[front->x][front->y+1]!='X'))

{

if(Amatrix[front->x][front->y+1]=='o')

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->y++;

score++;

flag=1;

}

else

{

p=(struct Snake*)malloc(sizeof(struct Snake));

p->x=front->x;p->y=front->y;p->body='X';p->next=front->next;

front->next=p;front->y++;

for(p=front;p!=rear;q=p,p=p->next);

Amatrix[p->x][p->y]=' ';

free(p);

rear=q;

q->next=NULL;

p=q=NULL;

}

}

else if(((dir=='d')&&(Amatrix[front->x][front->y+1]=='|')||(Amatrix[front->x][front->y+1]=='X'))||((dir=='a')&&(Amatrix[front->x][front->y-1]=='|')||(Amatrix[front->x][front->y-1]=='X'))||((dir=='s')&&(Amatrix[front->x+1][front->y]=='-')||(Amatrix[front->x+1][front->y]=='X'))||((dir=='w')&&(Amatrix[front->x-1][front->y]=='-')||(Amatrix[front->x-1][front->y]=='X')))

{

system("cls");

printf("******************************************************************************\n");

printf("* *\n");

printf("* *\n");

printf("* *\n");

printf("* GAME OVER *\n");

printf("* *\n");

printf("* *\n");

printf("******************************************************************************\n");

printf(" Your score is %d \n",score);

printf(" 屌丝梦工厂出品 (ˉ﹃ˉ) copyright by Frost.\n");

printf("请输入你的名字:");

scanf("%s",name);

if(strcmp(name,love)==0)

printf(" 我喜欢你。 \n");

else

printf("%s ,不再来一发吗,少年(■ ▽■)y-~~ 5s后重开\n",name);

if(score>=20)

printf("话说你是开挂的吧?\n");

Sleep(5000);

goto loop;

}

if(flag==1)

{

a.x=rand()%20+1;

a.y=rand()%60+1;

if((a.x==0)||(Amatrix[a.x][a.y]=='X')||(Amatrix[a.x][a.y]=='H'))

a.x=10;

if((a.y==0)||(Amatrix[a.x][a.y]=='X')||(Amatrix[a.x][a.y]=='H'))

a.y=30;

Amatrix[a.x][a.y]='o';

flag=0;

}

for(p=front;p!=NULL;p=p->next)

Amatrix[p->x][p->y]=p->body;

system("cls");//把刚才的屏幕上的东西抹掉,再重新输出数组,就能产生蛇移动的效果

for(i=0;i<24;i++)

{

puts(Amatrix);

}

printf("↑=w,↓=s,←=a,→=d撞墙、自食或者逆行必死,按d开始,渣画面勿喷");

}

system("cls");

for(i=0;i<24;i++)

{

puts(Amatrix);

}

printf("↑=w,↓=s,←=a,→=d撞墙、自食或者逆行必死,按d开始,渣画面勿喷");

}

return 0;

}[/mw_shl_code]

求糖.....#im

[查看全文]
foodszhu
姬宅百度贴吧的自动签到菜鸟脚本教程(三)gae篇
展开Biu

本帖最后由 foodszhu 于 2012-11-23 00:28 编辑

经过上两篇姬宅百度贴吧的自动签到菜鸟脚本教程(一)登陆篇,[url=姬宅百度贴吧的自动签到菜鸟脚本教程(二)签到篇 https://www.gn00.com/t-162458-1-1.html]姬宅百度贴吧的自动签到菜鸟脚本教程(二)签到篇[/url]。基本的脚本我们已经彻底完成了,也完成了一键签到的功能,

但是如果我们有一段时间不能用电脑,或者晚上懒得12点才睡去抢签怎么办?这里简单介绍一下如何将程序部署到google app engine上并使用cron job计划任务帮我们自动执行。

当然大家可以直接去看google给的教程,比我讲的好很多,不过中文教程还是python2.5的。。如果要用2.7还是看英文的


首先我们需要去google申请一个账户,并登陆appengine.google.com来创建自己的第一个应用,一旦创建好我们就有一个免费的二级域名来对我们的应用进行访问。申请好后去GAE 的SDK下载页面下载最新的SDKhttps://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Python,然后配置下环境变量就可以开始了。。

对于我们这种几乎几乎全后台的脚本。。如果不写前端的话还是很容易的。。

先写app.yaml,对于我而言,我的应用名叫autologin-foodszhu.

[mw_shl_code=text,true]application: autologin-foodszhu

version: 2

runtime: python27

api_version: 1

threadsafe: false

handlers:

- url: /all

script: loginAll.py[/mw_shl_code]

这个loginAll.py就是我们写的一键签到的脚本

然后再完成cron.yaml来完成定时任务[mw_shl_code=text,true]

cron:

- description: daily login job

url: /all

schedule: every 1 mins from 0:00 to 0:20

timezone: Asia/Shanghai

- description: every mouth clear job

timezone: Asia/Shanghai[/mw_shl_code]

这个cron我们在schedule种定义每天0:00到0:20每过一分钟,都运行一次loginAll的脚本。因为害怕如果只在0:00运行一次,很容易超时,而gae每个响应至多只能有30s时间,超过就会错误。。所以我们在这段时间内多次运行。

然后用appcfg.py将自己的应用部署上去即可


这就算简单的完成了,如果没什么特殊要求。。这样做一般可以保证每日都会签到。。

但是如果你要签到的贴吧数较多,而百度每日只允许签到100个贴吧,但是你用程序签到并不管你这个真的签到成功与否,反正执行一次,便多记录你你签到贴吧数目一个。这样,在0:00至0:20中多达20次的请求很容易将100个名额用完。这时我们便要将已经签到过的贴吧保存下来,下次签到时不再签到。。这也是为什么qiandaoAll方法会有一个except_list的原因。

由于GAE不允许本地文件的写入,所以我们必须用它给的数据存储区功能,好吧。。。其实我也只是照着写。。。没有仔细研究过。。

首先引入数据存储区的模块[mw_shl_code=python,true]from google.appengine.ext import db[/mw_shl_code]

在qiandao模块中,我们加入一个数据存储模型

[mw_shl_code=python,true]class QiandaoResult(db.Expando):

name=db.StringProperty()

no=db.IntegerProperty()

isQiandao=db.BooleanProperty()

time=db.DateTimeProperty()[/mw_shl_code]

提供了几个简单的属性,name为名字,no为返回代码,isQidandao记录是否签到成功,time记录本次签到的时间。因为我们不希望只记录下这几个信息,所以我们从db.Expando

DateTimeProperty 属性类支持tzinfo来对时区进行转换,数据存储区的数据自动转换为UTC时区,但是我们毕竟还是Asia/Shanghai的时区,所以我们要自己转换。

datetime模块中的tzinfo只是一个抽象类,并没有具体实现,所有我们可以采用一个第三方模块pytz,来帮我们转换,不过第三方模块部署时要一并附在应用目录下。pytz只有2mb大小,不算大,如果实在嫌大,可将pytz下zoneinfo中无关文件全部删掉。。只留我们需要的时区。

这时可以对我们的analyseQiandaoResult方法进行一定修改

[mw_shl_code=applescript,true]def analyseQiandaoResult(self,tieba_name,response):

now=datetime.datetime.now(pytz.timezone('Asia/Shanghai'))

result=json.loads(response)

no=result['no']

error=result['error']

if no == 0:

result=result['data']['uinfo']

result[u'tieba_name']=tieba_name.decode('utf-8')

dataStore=QiandaoResult(name=self.name,no=no,isQiandao=True,time=now)

for key,value in result.iteritems():

dataStore.__setattr__(key,value)

else:

result=tieba_name,error

dataStore=QiandaoResult(name=self.name,no=no,isQiandao=False,time=now)

dataStore.error=error

dataStore.tieba_name=tieba_name

if no == 1101 or no == 1007:

dataStore.isQiandao=True

dataStore.put()

return no,result[/mw_shl_code]

[mw_shl_code=python,true]now=datetime.datetime.now(pytz.timezone('Asia/Shanghai'))[/mw_shl_code]

来申明一个datetime对象记录在'Asia/Shanghai下的当前时间

[mw_shl_code=python,true]dataStore=QiandaoResult(name=self.name,no=no,isQiandao=True,time=now)

for key,value in result.iteritems():

dataStore.__setattr__(key,value)[/mw_shl_code]

初始化实体并添加动态属性方便我们日后提取调用。。

[mw_shl_code=python,true]dataStore.put()[/mw_shl_code]

提交实体。。

在loginAll里对已存储的实体进行查询

[mw_shl_code=applescript,true]today=datetime.datetime.combine(datetime.date.today(),datetime.time(tzinfo=pytz.timezone('Asia/Shanghai')))

jishuzhai=qiandao.JishuzhaiQiandao()

jishuzhai.login()

if not db.GqlQuery("SELECT * FROM QiandaoResult WHERE name = :1 AND isQiandao = True",jishuzhai.name).get():

jishuzhai.qiandao()

baidu=qiandao.TiebaQiandao()

baidu.login()

qbaidu=list(db.GqlQuery("SELECT * FROM QiandaoResult WHERE name = :1 AND isQiandao = True AND time >= :2",baidu.name,today))

response_list=baidu.qiandaoAll(*[item.tieba_name for item in qbaidu])[/mw_shl_code]

定义一个每天0:00的datetime对象,通过对这个对象的不等式查询,来确定今天的已签到的贴吧,最后对未签到的贴吧进行签到。。可以减少签到次数


但是实际应用对签到速度的提升并不明显。。。关键在于每晚gae对百度登陆都很卡。。姬宅的完全无压力。。。贴吧签到就只能慢慢跑了。。

最后放上自己在gae部署的程序,大家自己改下appid和用户名密码什么就可以用了。。

autologin.zip(54.27KB)

[查看全文]
foodszhu
姬宅百度贴吧的自动签到菜鸟脚本教程(二)签到篇
展开Biu

本帖最后由 foodszhu 于 2012-11-21 00:23 编辑

继续前一篇的内容,姬宅百度贴吧的自动签到菜鸟脚本教程(一)登陆篇

(一)准备

其实经过上一篇所讲,签到也是一个类似的过程

这次我们用firefox的firebug插件为例来探究下签到的过程

1.姬宅签到:

因为自己自从写了这个脚本之后就真的自动签到了。。所以新建了一个号来截图。。不过用户组在loading下无法完成签到,不过仍可以登陆进签到中心,来查看提交的表单,跟在主页签到完全一样。进入页面打开firebug,进入网络分页,点击保持按钮保证处于保持状态,然后选好参数,这里我选择不想填写,签到心情是慵懒。单击开始签到

同登陆时一样,是一个post表单,url是https://www.gn00.com/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1&inajax=1,qdmode是签到模式,貌似1是自己填写,3是不想填写,2是什么不清楚,qdxq是签到心情,yl是慵懒。。好吧都是拼音。。

这些都是可以固定下来或者随机选取的。而唯一看似重要的formhash是什么呢?我们打开页面的源代码进行搜索。。

表单处理那发现这么一行[mw_shl_code=html,true]<form id="qiandao" method="post" action="plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1">

<input type="hidden" name="formhash" value="05bdef8b">[/mw_shl_code]

明显为我们所需。。在登陆的基础上,签到明显是个简单活动

2.贴吧签到

以bilibili吧为例

登陆bilibili吧,单击签到,

也是post表单,url为http://tieba.baidu.com/sign/add,三个参数也十分简单

ie估计是编码格式,kw为贴吧名称,tbs估计为贴吧的代码,打开源代码进行搜索

[mw_shl_code=html,true] *本站禁止HTML标签噢*

PageData.tbs = "483101895300e4521353410592";[/mw_shl_code]

可查到这么一行,说明tbs也可从本页面直接获取。

需要注意的是,中文贴吧名在转化为url时,必须是由gbk码转换成url。才能正常访问

把所需要的数据放在qiaodao.ini中方便读取

[mw_shl_code=text,true]#qiandao.ini

[技术宅]

url=https://www.gn00.com

qiandao_url=https://www.gn00.com/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1&sign_as=1&inajax=1

fastreply=0

formhash=

qdmode=3

qdxq=fd

todaysay=

[百度]

url=http://www.baidu.com

qiandao_url=http://tieba.baidu.com/sign/add

ie=utf-8

kw=

tbs=[/mw_shl_code]

不过单纯一个贴吧的签到当然无法满足我们,我们要尝试下签到所有喜欢的贴吧,第一步,就要找出自己的喜爱的贴吧。

这里我提供两种方案

1.通过http://www.baidu.com/p/用户名?from=tieba进入到百度个人主页的我在贴吧子页,从中获取我最喜爱的吧。

2.在登陆状态下,通过http://tieba.baidu.com/i/sys/enter?ie=utf-8&kw=用户名进入到个人的i贴吧,从中提取我爱逛的贴吧。

具体操作稍后再讲

相比登陆方面,签到简直是没有任何难度。。。所以我们就要在脚本上下点功夫了


(二)脚本

先上总脚本,这个签到本来是一件非常简单的事,但是不比登陆,我们往往需要获得一些签到返回的信息,所以对返回信息稍作处理

[mw_shl_code=python,true]#!/usr/bin/env python

# -*- coding: utf-8 -*-

#

# qiandao.py

import login,re,urllib,urllib2,json,threading

import ConfigParser as cp

class Qiandao(login.Login):

def __init__(self,name):

super(Qiandao,self).__init__(name)

self.loadIni('qiandao.ini',name,self.data,'url','qiandao_url')

def qiandao(self):

data = urllib.urlencode(self.data)

req = urllib2.Request(self.qiandao_url,data,self.headers)

response = self.opener.open(req)

self.qiandao_response=response

self.qiandao_response_read=response.read().decode('utf-8')

return self.qiandao_response_read

class TiebaQiandao(Qiandao,login.BaiduLogin):

def __init__(self,name='百度'):

self.result_list={u'cont_sign_num':u'连续签到天数', u'cout_total_sing_num':u'本月累计签到天数',u'user_sign_rank':u'个人签到排名',u'tieba_name':u'贴吧'}

super(TiebaQiandao,self).__init__(name)

def getTiebaKw(self,name):

return urllib2.quote(name.decode('utf-8').encode('gbk'))

def getTiebaTbs(self,name):

url='http://tieba.baidu.com/f?kw='+self.getTiebaKw(name)

buf=self.opener.open(url).read()

s=r'PageData.tbs = \"(\w+)\"'

t=re.findall(s,buf)[0]

return t

def qiandao(self,tieba_name):

self.setData(kw=tieba_name,tbs=self.getTiebaTbs(tieba_name))

response=super(TiebaQiandao,self).qiandao()

return tieba_name,response

def qiandaoAll(self,*except_list):

self.qiandao_response_list=[self.qiandao(item) for item in self.getAllTiebaList() if item not in except_list]

return self.qiandao_response_list

def getAllTiebaList(self):

#url='http://www.baidu.com/p/%s?from=tieba' % self.getTiebaKw(self.data['username'])

#r=r'target=_blank title=\\x22(.*?)\\x22'

#for i,v in enumerate(l):

# l=v.rstrip('\xe5\x90\xa7')

#return l

url='http://tieba.baidu.com/i/sys/enter?ie=utf-8&kw=%s' % self.getTiebaKw(self.data['username'])

r=r'\$_likeForum=(.*?);'

buf=self.opener.open(url).read()

l=re.findall(r,buf)[0]

j=json.loads(l)

l=[]

for i in j:

l.append(i['name'].encode('utf-8'))

print i['name'].encode('utf-8')

return l

def analyseQiandaoResult(self,tieba_name,response):

result=json.loads(response)

no=result['no']

error=result['error']

if no == 0:

result=result['data']['uinfo']

result[u'tieba_name']=tieba_name.decode('utf-8')

else:

result=tieba_name,error

return no,result

def printQiandaoResult(self,no,result):

if no == 0:

for key,value in self.result_list.items():

print "%s : %s" %(value,result[key])

else:

print "贴吧 : %s" %result[0]

print '签到失败 : %s'%result[1].encode('utf-8')

print ''

class JishuzhaiQiandao(Qiandao,login.JishuzhaiLogin):

def __init__(self,name='技术宅'):

super(JishuzhaiQiandao,self).__init__(name)

def getFormHash(self):

buf=self.opener.open(self.url).read().decode('utf-8')

r=r'formhash=\w+'

s=re.findall(r,buf)[0].split('=')[1]

return s

def qiandao(self):

self.setData(formhash=self.getFormHash())

response = super(JishuzhaiQiandao,self).qiandao()

return response

def analyseQiandaoResult(self):

r=r'<div class="c">\r\n(.*?) </div>'

result=re.findall(r,self.qiandao_response_read)[0]

if u'成功' in result:

no=0

else:

no=1

return no,result

def printQiandaoResult(self):

no,result=self.analyseQiandaoResult()

print '技术宅社区:'

if no == 0:

print '签到成功:'

else:

print '签到失败:'

print result

print ''

def main(name):

if name=='技术宅':

website=JishuzhaiQiandao()

website.login()

website.qiandao()

website.printQiandaoResult()

elif name=='百度':

tieba_name=raw_input("输入您想签到的贴吧名称(如果想签到所有喜欢贴吧请打all):").lower()

website=TiebaQiandao()

website.login()

if tieba_name != 'all':

website.printQiandaoResult(*website.analyseQiandaoResult(*website.qiandao(tieba_name)))

else:

response_list=website.qiandaoAll()

for item in response_list:

website.printQiandaoResult(*website.analyseQiandaoResult(*item))

else:

print '没有填写配置文件!'

return 1

return 0

if __name__ == '__main__':

name=raw_input('输入您想登陆的网站名称(确保您已填写配置文件):')

main(name)

[/mw_shl_code]

[mw_shl_code=python,true]import login,re,urllib,urllib2,json

import ConfigParser as cp[/mw_shl_code]

依旧是首先引入模块,这里需要引入上篇我们写的登陆模块。。

[mw_shl_code=python,true]class Qiandao(login.Login):

def __init__(self,name):

super(Qiandao,self).__init__(name)

self.loadIni('qiandao.ini',name,self.data,'url','qiandao_url')

def qiandao(self):

data = urllib.urlencode(self.data)

req = urllib2.Request(self.qiandao_url,data,self.headers)

response = self.opener.open(req)

self.qiandao_response=response

self.qiandao_response_read=response.read().decode('utf-8')

return self.qiandao_response_read[/mw_shl_code]

同样是先构造签到的基类,由于签到是基于登陆完成,且两者有很多共同之处,所以将Login类设为Qiandao类的基类,可以省下很多操作

初始化时多一步读取qiandao.ini的内容作为表单值。

定义新的方法qiandao作为签到的实际做法,不过跟登陆的做法极为类似,只是换掉了登陆的url而已,不过这个qiandao必须在已登陆的前提下再进行签到。

[mw_shl_code=python,true]class TiebaQiandao(Qiandao,login.BaiduLogin):

def __init__(self,name='百度'):

self.result_list={u'cont_sign_num':u'连续签到天数', u'cout_total_sing_num':u'本月累计签到天数',u'user_sign_rank':u'个人签到排名',u'tieba_name':u'贴吧'}

super(TiebaQiandao,self).__init__(name)

def getTiebaKw(self,name):

return urllib2.quote(name.decode('utf-8').encode('gbk'))

def getTiebaTbs(self,name):

url='http://tieba.baidu.com/f?kw='+self.getTiebaKw(name)

buf=self.opener.open(url).read()

s=r'PageData.tbs = \"(\w+)\"'

t=re.findall(s,buf)[0]

return t

def qiandao(self,tieba_name):

self.setData(kw=tieba_name,tbs=self.getTiebaTbs(tieba_name))

response=super(TiebaQiandao,self).qiandao()

return tieba_name,response

def qiandaoAll(self,*except_list):

self.qiandao_response_list=[self.qiandao(item) for item in self.getAllTiebaList() if item not in except_list]

return self.qiandao_response_list

def getAllTiebaList(self):

#url='http://www.baidu.com/p/%s?from=tieba' % self.getTiebaKw(self.data['username'])

#r=r'target=_blank title=\\x22(.*?)\\x22'

#for i,v in enumerate(l):

# l=v.rstrip('\xe5\x90\xa7')

#return l

url='http://tieba.baidu.com/i/sys/enter?ie=utf-8&kw=%s' % self.getTiebaKw(self.data['username'])

r=r'\$_likeForum=(.*?);'

buf=self.opener.open(url).read()

l=re.findall(r,buf)[0]

j=json.loads(l)

l=[]

for i in j:

l.append(i['name'].encode('utf-8'))

print i['name'].encode('utf-8')

return l

def analyseQiandaoResult(self,tieba_name,response):

result=json.loads(response)

no=result['no']

error=result['error']

if no == 0:

result=result['data']['uinfo']

result[u'tieba_name']=tieba_name.decode('utf-8')

else:

result=tieba_name,error

return no,result

def printQiandaoResult(self,no,result):

if no == 0:

for key,value in self.result_list.items():

print "%s : %s" %(value,result[key])

else:

print "贴吧 : %s" %result[0]

print '签到失败 : %s'%result[1].encode('utf-8')

print ''

[/mw_shl_code]

当签到的基类构造好时我们就要构造下一步的子类了,但是在登陆基类我们已经派生出两个子类BaiduLogin和JishuzhaiLogin,来分别处理百度与姬宅的登陆,所以我们既需要从登陆的两个子类中继承需要的功能,又需要从签到基类中继承所需要的功能,所以我们采用多继承的方法。

在我们的TiebaQiandao类中,我们既继承了BaiduLogin类,又继承了Qiandao类,为了防止共同父类方法的多次调用,我们采用super来调用父类的方法。

super是采用mro方式处理多继承中共同方法的多次调用的问题的,所以为了运行良好,我们必须将所有的调用父类的形式都改为super

同时,由于新型类中,mro顺序是广度优先的,所以同层间的相同方法最好使用相同的参数个数,否则就可能报错,而且达不到我们想要的结果。关于这部分的讨论,搜索一下python的多继承

[mw_shl_code=python,true]def getTiebaKw(self,name):

return urllib2.quote(name.decode('utf-8').encode('gbk'))

def getTiebaTbs(self,name):

url='http://tieba.baidu.com/f?kw='+self.getTiebaKw(name)

buf=self.opener.open(url).read()

s=r'PageData.tbs = \"(\w+)\"'

t=re.findall(s,buf)[0]

return t[/mw_shl_code]

这两个函数是为了得到签到的表单项之一的tbs,我们从该贴吧的页面中获取信息,所以得先进入这个贴吧,

而贴吧url形式为http://tieba.baidu.com/f?kw=贴吧名,当然贴吧名需要处理为url能识别的形式,而且得从gbk码转换而来,由于我编码的统一为utf-8,所以要做进一步转换

同样用正则表达式将tbs挑捡出来

[mw_shl_code=python,true]def getAllTiebaList(self):

#url='http://www.baidu.com/p/%s?from=tieba' % self.getTiebaKw(self.data['username'])

#r=r'target=_blank title=\\x22(.*?)\\x22'

#for i,v in enumerate(l):

# l=v.rstrip('\xe5\x90\xa7')

#return l

url='http://tieba.baidu.com/i/sys/enter?ie=utf-8&kw=%s' % self.getTiebaKw(self.data['username'])

r=r'\$_likeForum=(.*?);'

buf=self.opener.open(url).read()

l=re.findall(r,buf)[0]

j=json.loads(l)

l=[i['name'].encode('utf-8') for i in j]

return l[/mw_shl_code]

getAllTiebaList是获取喜爱贴吧的方法,其中我注释的部分是我在准备篇中所说的第一种方法,即进入到个人主页中提取。。其中包含在target=_blank title=后面的即是贴吧名,不过后面多了一个吧字,在这里我们用rstrip将其消掉,字符串rstrip方法用于消去共同后缀,rstrip消去共同前缀,使用默认参数时消去空格

第二种方法,即在登陆前提下,进入个人的i贴吧,从中获取贴吧信息,而这个部分信息较为混杂,我们仔细查看,发现在响应的末尾有一组以脚本形式存储的信息,以$_likeForum开头的数据

我们先用re模块将字符串提取出来,注意$需要转义所以加\,然后用json模块将字串转化为我们能够直接用的对象,在这里面会生成一组列表,列表中每一项都是一个字典,包括了爱逛的贴吧的信息,这里我们暂且只用name这一对键值,同时用了列表推导的技巧生成了这个列表

[mw_shl_code=python,true]def qiandao(self,tieba_name):

self.setData(kw=tieba_name,tbs=self.getTiebaTbs(tieba_name))

response=super(TiebaQiandao,self).qiandao()

return tieba_name,response[/mw_shl_code]

qiandao方法是对父类的签到方法的具体实现,对于贴吧签到而言,我们不仅需要登陆百度,而且还需要知道所要签到的贴吧名,在加上贴吧的tbs后,发送表单完成签到

同时返回贴吧名与响应的元组

[mw_shl_code=python,true]def analyseQiandaoResult(self,tieba_name,response):

result=json.loads(response)

no=result['no']

error=result['error']

if no == 0:

result=result['data']['uinfo']

result[u'tieba_name']=tieba_name.decode('utf-8')

else:

result=tieba_name,error

return no,result[/mw_shl_code]

analyseQiandaoResult方法正是为了分析qiandao方法返回响应的方法,它所需参数正好是签到返回的结果,而这个响应结果,直接是以json形式存储的,所以我们可以用json模块直接提取出来,其中no是返回代码,0即登陆成功,1101代表已经登陆,1007代表今天签到次数超过100次,error即错误说明。

如果签到成功,响应中data对应值即是一些个人排名啊,贴吧排名,贴吧目录等项,uinfo代表个人信息,我们这里只取个人信息保存。最终返回响应代码与一个打包好的字典作为返回结果

[mw_shl_code=python,true]def printQiandaoResult(self,no,result):

if no == 0:

for key,value in self.result_list.items():

print "%s : %s" %(value,result[key])

else:

print "贴吧 : %s" %result[0]

print '签到失败 : %s'%result[1].encode('utf-8')

print ''[/mw_shl_code]

从分析结果中我们最终打印出我们需要的结果。。这块就不多说了。

[mw_shl_code=python,true]def qiandaoAll(self,*except_list):

self.qiandao_response_list=[self.qiandao(item) for item in self.getAllTiebaList() if item not in except_list]

return self.qiandao_response_list[/mw_shl_code]

qiandaoAll方法用于签到所有爱逛的贴吧,参数中except_list用于设定无需签到的贴吧,这里其实可以用多线程,不过仔细想想还是觉得略麻烦而且在gae上部署也很麻烦多以就放弃了

姬宅的签到与贴吧签到类似,只需要加上一个formhash即可提交。当然两者都需要先login,再qiandao


最后我们就可以来个一键签到了

[mw_shl_code=python,true]#!/usr/bin/env python

# -*- coding: utf-8 -*-

#

# 一键签到.py

#

import qiandao,os

def main():

jishuzhai=qiandao.JishuzhaiQiandao()

baidu=qiandao.TiebaQiandao()

jishuzhai.login()

baidu.login()

jishuzhai.qiandao()

jishuzhai.printQiandaoResult()

response_list=baidu.qiandaoAll()

for item in response_list:

baidu.printQiandaoResult(*baidu.analyseQiandaoResult(*item))

return 0

if __name__ == '__main__':

main()[/mw_shl_code]

将这个代码文件设为可执行,需要签到时运行即可


自动签到的主体部分就到此结束了。。。

下来一篇就是将如何将这个脚本部署在gae上,并且用计划任务在12点附近进行签到。。。不过gae要求只能有最多30s的响应时间所以12点刚过那阵贴吧签到各种Deadline exceeded。。。。几乎到快到20才能勉强签上。。不知为何。。暂时也没有用多线程。。难道只有用多线程才能改进一下么

恩恩。。下一篇就是部署到gae上,并进行少量优化


发帖果然理会的人不多啊。。。而且自己话也说不太清楚。。。自己第一次写教程也请各位见谅。。

再。。求发糖#18t

[查看全文]
轻舟过
[Python] 解迷宫的程序
展开Biu

顺便博客求关注:http://bimania.org/

在stackoverflow上看到一个有趣的问题:给定一张图片,如何表示并解决图片上的迷宫。

自己也写了一下,稍微用qt做了个界面。其实并没有用到什么很难的算法,只是一个简单的BFS。

当然迷宫上会有一个入口和出口,首先需要自己对图片做下预处理,把入口和出口封住,否则最后算出的最短路径将是从迷宫外面的空白区域绕过去的。另外程序运行之后还要用鼠标确定起点和终点,剩下就是从起点开始进行BFS,直到到达终点。另外需要注意的是边界和路径的区分,这个是通过计算像素点的灰度值,将灰度值超过一定限度的作为边界,低于的作为可以通过的区域。

[mw_shl_code=python,true]

import sys

import os

from PyQt4.QtGui import *

from PyQt4.QtCore import *

from collections import deque

class State:

def __init__(self, x, y, pre=None):

self.x = x

self.y = y

self.pre = pre

def __str__(self):

return "(%d, %d)" % (self.x, self.y)

class MazeLabel(QLabel):

def __init__(self, pixmap, path, parent=None):

QLabel.__init__(self, parent)

self.setPixmap(pixmap)

self.path = path

self.p1 = None

self.p2 = None

def isWhite(self, c):

if abs(qGray(c) - qGray(qRgb(255, 255, 255))) < 30:

return True

else:

return False

def solve(self, img):

q = deque()

q.append(State(self.p1.x(), self.p1.y()))

img.setPixel(self.p1.x(), self.p1.y(), qRgb(0, 0, 0))

print len(q)

#cnt = 100

while len(q) > 0:

s = q.popleft()

#print s

if s.x == self.p2.x() and s.y == self.p2.y():

return s

for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:

nx, ny = s.x + dx, s.y + dy

if nx >= 0 and nx < img.width() and ny >= 0 and ny < img.height() and self.isWhite(img.pixel(nx, ny)):

q.append(State(nx, ny, s))

img.setPixel(nx, ny, qRgb(0, 0, 0))

#cnt = cnt - 1

print "no solution!"

def mousePressEvent(self, ev):

if self.p1 == None:

self.p1 = ev.pos()

else:

self.p2 = ev.pos()

print self.p1

print self.p2

image = self.pixmap().toImage()

sol = self.solve(image)

image = self.pixmap().toImage()

it = sol

while it != None:

image.setPixel(it.x, it.y, qRgb(255, 0, 0))

it = it.pre

self.setPixmap(QPixmap.fromImage(image))

self.update()

fileName, fileExt = os.path.splitext(self.path)

newFileName = fileName + "_solved" + fileExt

self.pixmap().save(newFileName)

if __name__ == "__main__":

app = QApplication(sys.argv)

scrollArea = QScrollArea()

pixmap = QPixmap(sys.argv[1])

imageLabel = MazeLabel(pixmap, sys.argv[1])

scrollArea.setWidget(imageLabel)

scrollArea.show()

app.exec_()

[/mw_shl_code]

下面是一个迷宫的例子,非常复杂,入口在左上角,出口在右下角

不过用程序,很容易能得出啊答案,下面是程序给出的解

[查看全文]
基叔
android应用开发------1.工具选择和demo
展开Biu

本帖最后由 基叔 于 2012-11-1 21:56 编辑

前言

开发android应用当然要直接在android手机上开发,

集开发调试于一身。多方便。 不需要在电脑上安装什么东西,简单粗暴。

这次就是给大家带来两个手机上的应用,

一个是编码器,一个是我自己弄的应用Run!

可以让你直接在手机上开发运行并调试应用,工作原理是基于phonegap

这个东西我在下次介绍如何发布我们的应用时一起说明。

正文

重复一遍好了:我们这次是介绍在手机上开发!

搭建的是开发与调试和运行环境,发布应用的环境以后讲。

1:环境搭建 下载这玩意儿安装在你android手机里 戳我 run.apk 这个就是我们依赖的环境了,

还有这个东西 我们的编辑器 Droidedit 一起安装

2:下载这个www.zip,把里面的东西解压到你sdcard根目录。没有外置卡的同学解压到手机内部存储的根目录就可以了

3:戳开手机上的Run!应用

现在你可以玩一下那个应用。开始讲开发啦

点开Droideidt 输入这个

编写里面的内容 如下

[mw_shl_code=xhtml,true] *本站禁止HTML标签噢* hello world</h1>[/mw_shl_code]

保存起来,命名为index.html,扔进之前的www文件夹,覆盖掉原来的index.html

然后重新戳开那个Run! 看看有什么变化捏

恩恩这个就是简单的hello world 了....由于前言写太多了,其他的教程部分下次写吧

布置一下作业,比如自己写不一样的index.html放进去,看看是什么样子呢~

下次讲怎么完善和怎么发布应用。拜拜

[查看全文]
秋声赋
简单易懂的现代魔法:C#编程教程(五) 简单计算器示例
展开Biu

本帖最后由 秋声赋 于 2012-6-4 11:57 编辑

简单易懂的现代魔法:C#编程教程()
简单计算器示例

很久没写了,主要是觉得4篇之后没什么人关注了...

本帖是很久以前就完成了的,只是一直没找到时间来发,乘着现在有时间,把这个帖子发出来.

本帖将带你们用C#做一个简单的计算器程序.

就像Windows自带的那样,当然只包括标准版,学会了标准版的做法,做其他类型的计算器就不难了,希望大家能举一反三把剩余的功能做出来.

本帖要求有基本的VS2010使用能力和知道C#的基本语法,就是前面的帖子说的那些,这算一个综合应用.

先说明一点,我会把源代码在附上,但是我更希望大家手打这些代码到编辑器中.手打的过程中能发现很多自己没注意的问题,而且代码并不多.

相应代码的逻辑,我会在代码中用注释表示出来,不会用文字写在帖子里面.

所以在介绍各个部分的时候,我会用图片的形式贴上代码,还一个原因就是论坛的代码高亮功能实在脑残,如果只有一种颜色,看代码会有些吃力.
//====================================================================================\\

首先我们来介绍一下我们要做的这个计算器的功能和大概思路.

上面是程序的界面,2个文本框(TextBox)23个按钮(Button)控件所构成.

如字面所说,他具有一个简单计算器的功能,可以通过按钮和键盘输入,上面一个文本框是显示当前的计算式,下面是结果.如果还有不明白的可以打开Windows自带的计算器试验一下.

思路如下:
1. 我们需要一个枚举来记录我们当前的操作符.
2. 分为3种按钮:数字,操作符,退格键.分别对应3个响应函数.
3. 通过读取按钮上的文字来判断各个按钮的功能.
4. 因为输入全为个位整数,用小数点和小数点后面的数的数目表示小数.
5. 通过下面的文本框记录和传递所输入的数字

了解了这些,我们就可以开始制作我们的计算器了.

首先打开VS2010建一个C#Windows窗体应用程序(WinForm)

然后从工具箱中拖出2TextBox控件23Button控件摆放如下图:

并为每一个控件命名和修改Text属性(显示的字符),为了增加程序的可读性,

为每一个按钮和文本框都取上代表其含义的名字.具体可以看后面我发的源代码.

这是系统自动生成的代码,最后面就是按钮的名字,不要吐槽我的英语,一直在及格边缘徘徊.

然后就进入代码编辑页面.

根据上面的分析,我们首先要一个枚举来标识运算符(其实只用数字也能记录,但是为了程序的可读性和安全性,我们选择枚举来记录).定义如下

然后我们需要几个变量来帮助我们记录当前的状态.(无视图片中全局2个字)

Operators是我们刚刚定义的枚举噢.

接着是完成4消息响应函数,这是整个程序的核心,他们分别是:

数字按钮消息响应函数(number_click),

操作符按钮响应函数(button_Oper_Click),

退格键按钮响应函数(BT_BACK_Click),

文本框键盘消息响应函数(TB_FORMULA_KeyDown).

首先在按钮的[属性]—[事件]处为每一个按钮添加相应的事件.并双击函数名进入代码编辑状态.

注意不要用自动生成的函数!要自己取函数名,且响应的按钮类别对应响应的响应函数.

最先讲下数字按钮消息响应函数(number_click).这个函数的目的是处理用户按下按钮的Click事件,

记录按下按钮对应的数字,并根据当前的状态(是否有小数点)来保存数字,并修改文字框TB_FORMULA所显示的数字.代码和原理如下所示:

然后是最复杂的操作符按钮响应函数,这个函数的目的是响应用户按下的操作符按钮,

当一个操作符按钮被按下时,系统要根据上一个运算符来对当前的数字进行一定的操作.

并根据按钮的文本判断是那种操作符,并记录下来,不同的操作符也对应了不同的操作.主要用到了Case分支语句,代码如下:

接下来是退格键响应函数(BT_BACK_Click),他的作用是响应退格键,并从2个文本框里面删除最后一位,

并更新记录输入数据的变量.代码如下:

最后是键盘响应函数,首先为我们的TB_EXPRESSIION文本框添加一个KeyDown事件的消息响应函数TB_FORMULA_KeyDown.如下图所示.

那怎么发生相应的消息呢?我们是用模拟用户点击按钮的方法实现.

首先判断用户按的是那个键,再调用相应的按钮响应函数,并把相应的按钮当做参数发送给响应函数.

例如当用户按下小键盘的1,因为他是数字按钮,我们就调用number_click函数,并把他的第一个参数(objectsende)设置为BT_1表示用户按了1的按钮.至于第二个参数,因为我们不要用他,把他设为null就行.代码如下:

其中Keys里面有所有键盘按键对应的代码,例如NumPad1就是小键盘1的意思.

到这里我们的计算器就做好了,大家可以编译并运行试一下效果.

如果有不懂的地方可以回帖问我.

下面布置个作业:做出Windows自带的计算器的科学型.

[查看全文]