自己写的一个 hacker.org 模板
在人人上看到好多大牛在刷hacker.org,打开看也不知道怎么玩,后来Su_Xing老祖告诉了我hacker.org的玩法:
Challenge是各种类型的小谜题闯关,跟那些解密闯关的网页游戏类似,需要很广泛的知识
Bot Wars貌似是写AI的,暂时还没有研究过
Puzzles就是一些小游戏,这些游戏在网页源码里可以得到相应的游戏信息,把信息抓取出来,然后一番计算之后把答案在URL后面贴出来就可以到达后面一关,下面主要说的就是这个了
这些小游戏可以通过搜索来解决,但是越往后面越是复杂,就需要很好的算法,是很好的练习搜索能力的题目。相比ACM而言,这个的限制更为宽松,你可以不择手段,什么多线程都可以用,甚至可以搭载几台电脑并行去算,只要能把答案算出来就Ok了,也不限制时间和内存。
抓取信息和回馈答案都可以用脚本轻松实现,但是脚本的运行速度相比C/C++而言慢了不是一个数量级,所以我用前两天学的socket,将脚本抓取出来的信息发送到C++程序中,运算之后再发送回去,这样的方法写了一个模板:
1 import urllib2
2 import socket
3 import re
4
5 game = 'XXXX'
6 name = 'XXXX'
7 pswd = 'XXXXXX'
8 url = 'http://www.hacker.org/%s/index.php?name=%s&password=%s' % (game, name, pswd)
9
10 print url
11
12 def read(_url):
13 content = urllib2.urlopen(_url).read()
14 flavars = re.compile('FlashVars=".*"').search(content).group()[11:-1]
15 return flavars
16
17 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
18 sock.connect(("127.0.0.1",5002))
19
20 nextl = url
21 while True:
22 case = read(nextl)
23 print case
24
25 sock.send(case)
26 ans = sock.recv(1024)
27 ans = re.compile('[^\0]*').search(ans).group()
28 print ans
29
30 nextl = url + '&path=' + ans
这是抓取的python脚本模板,需要安装py环境,稍微解释下代码:
5,6,7三行是要修改的内容,游戏名称,你的帐号和密码
8链接得到要发送的URL
12行的函数是发送URL,并在返回的html代码中取出FlashVars中的游戏关卡信息
17,18是初始化socket
20行之后就是主循环了,读取case,发送case,接收得到的答案字符串,1024是大小,接受的大小要根据不同谜题而修改,这里可以改的大一些,因为python的字符串不是以'\0'结束的,所以还要对ans进行处理,不然会返回404,然后连接得到下一关的URL
30行,连接URL时候要注意,有些谜题是"&path=",有些是"&sol=",还有别的,这个地方根据需要做相应的修改
然后在你要写的C++程序中加入下面一段:
1 //your include
2 #include<winsock.h>
3
4 SOCKET mysock;
5 void _init(){
6 SOCKET id;
7 WSADATA wsaData;
8 SOCKADDR_IN addr;
9
10 if(WSAStartup(MAKEWORD(2,0),&wsaData)){
11 printf("Socket Error!");
12 return;
13 }
14
15 id = socket(AF_INET, SOCK_STREAM, 0);
16 memset(&addr, 0, sizeof(addr));
17 addr.sin_family = AF_INET;
18 addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
19 addr.sin_port = htons(5002);
20 bind(id, (sockaddr *)&addr, sizeof(addr));
21
22 listen(id, 1);
23
24 SOCKADDR_IN Client;
25 int len = sizeof(SOCKADDR);
26
27 mysock = accept(id,(SOCKADDR *)&Client,&len);
28 }
29
30 char msg[1024];
31 void _send(){
32 memset(msg,0,sizeof(msg));
33
34 //把你得到的答案转化成要求的字符串
35
36 send(mysock,msg,1024,0);
37 }
38
39 void _recv(){
40 recv(mysock, msg, 1024,0);
41 puts(msg);
42
43 //把msg字符串转化为你需要的变量值
44 }
45
46 int main(){
47 _init();
48
49 while(true){
50 _recv();
51
52 //运算得到答案
53
54 _send();
55 }
56
57 return 0 ;
58 }
我使用的编译器是MinGW,如果你使用的其他编译器,需要对其中的头文件进行相应修改,MinGW在连接时需要添加 -lwsock32 的控制项,_send() 和 _recv() 中的发送大小以及字符串 msg[] 的大小根据不同游戏做不同的修改,最好能保持一致,并和py中的相同。
由于C++代码是服务端,所以使用时先运行C++程序,然后再运行py程序。由于是自己玩的,上面两段代码没有进行任何错误的判定,所以使用时如果代码存在问题可能会遇到各种错误,两段代码也非常简单,想必看过之后就可以进行修改了~
本文地址:http://www.cnblogs.com/ambition/archive/2012/02/17/my_hacker.html