我先用看似单纯的批处理去实现CWHGN猜数字游戏,虽然批处理不支持发送请求,但凭借调用一个4行的外部js可以实现网络请求功能。索性集成到一个批文。由于该题目涉及到数组的频繁操作,每次post批处理需要先筛选几千次,因此 处理较大的数组 就暴露了其运行缓慢的缺陷:每分钟猜题速度10左右。若改用位运算可以缓解一些,但提速不大。测试效果和代码如下:
(图片引用均为外部链接)

[批处理实现]略带js混编 | 1>1/* : | | @echo off | | REM 开启变量延迟 | | setlocal enabledelayedexpansion | | | | REM 设置全局变量 | | set "USER_NAME=adad" | | set "PASS_WORD=123" | | set "POST_URL=http://www.codetiger.win/extra/API.php" | | | | REM 生成[0-9]的四位全排列数 | | set "PM_LENGTH=0" | | for /l %%i in (0,1,9) do ( | | for /l %%j in (0,1,9) do ( | | for /l %%k in (0,1,9) do ( | | for /l %%l in (0,1,9) do ( | | 2> NUL set/a "1/((%%i-%%j)*(%%i-%%k)*(%%i-%%l)*(%%j-%%k)*(%%j-%%l)*(%%k-%%l))" && ( | | set/a "PM_LENGTH+=1" | | set "PM[!PM_LENGTH!]=%%i%%j%%k%%l" | | ) | | ) | | ) | | ) | | ) | | | | REM 初始化标记数组 | | for /l %%i in (1,1,!PM_LENGTH!) do ( | | set "PM_MARK[%%i]=1" | | ) | | | | REM 初始化变量值 | | set/a "RESP_TOKENS=0, RESP_DATA=0, GUESS_TIMES=0, CUR_INDEX=1" | | | | REM 锚点 | | :LOOP1 | | REM 利用局部变量表,实现快速初始化 | | setlocal | | | | REM 内层循环 | | :LOOP2 | | REM 变量中转 | | for %%a in (!CUR_INDEX!) do ( | | set "GUESS_NUMBER=!PM[%%a]!" | | ) | | | | REM 向服务器发送请求,并处理返回json格式 | | for /f "tokens=2,4,6,8,10 delims=,:{}" %%a in ( | | | | REM 猜数计次器 | | set/a "GUESS_TIMES+=1" | | | | REM 显示界面 | | set/a "DIS_CUR_INDEX=10000+CUR_INDEX" | | echo #POST:{PM[!DIS_CUR_INDEX:~-4!]=!GUESS_NUMBER!} #RESP_JSON:{%%a %%b %%c %%d %%e} | | | | REM 网络检测器 | | if "%%e"=="" ( | | echo Requests error^^! | | endlocal | | goto :LOOP1 | | ) | | | | REM 答案验证器 | | if "%%b"=="4" ( | | echo Takes:[!GUESS_TIMES!th], Answer:!GUESS_NUMBER!, Score:[%%d] | | endlocal | | goto :LOOP1 | | ) | | | | REM TOKENS重置器 | | if "!RESP_TOKENS!"=="0" ( | | set "RESP_TOKENS=%%e" | | ) else ( | | if not "!RESP_TOKENS!"=="%%e" ( | | echo Reset... | | endlocal | | goto :LOOP1 | | ) | | ) | | | | REM 计算猜测权值 | | set/a "R_WEIGHTS=%%b*5+%%c, NEW_INDEX=0" | | | | REM 权值筛选器 | | for /l %%i in (1,1,!PM_LENGTH!) do ( | | if !PM_MARK[%%i]! equ 1 ( | | set "T_WEIGHTS=0" | | | | REM 数码比对器 | | for /l %%p in (0,1,3) do ( | | for /f "tokens=1,2" %%A in ("!PM[%%i]:~%%p,1! !CUR_INDEX!") do ( | | if not "!PM[%%B]:%%A=!"=="!PM[%%B]!" ( | | if "!PM[%%B]:~%%p,1!"=="%%A" ( | | set/a "T_WEIGHTS+=5" | | ) else ( | | set/a "T_WEIGHTS+=1" | | ) | | ) | | ) | | ) | | | | REM 筛选标记器 | | if !T_WEIGHTS! neq !R_WEIGHTS! ( | | set "PM_MARK[%%i]=0" | | ) else ( | | if !CUR_INDEX! neq %%i ( | | set "NEW_INDEX=%%i" | | ) | | ) | | ) | | ) | | | | REM 索引价值判定 | | if !NEW_INDEX! neq 0 ( | | set "CUR_INDEX=!NEW_INDEX!" | | goto :LOOP2 | | ) else ( | | echo Fault. | | endlocal | | goto :LOOP1 | | ) | | ) | | | | REM 内层循环结尾 | | goto :LOOP2 | | */ | | var xmlHTTP=new ActiveXObject( | | xmlHTTP.open( | | xmlHTTP.send(); | | WScript.echo(xmlHTTP.responseText);COPY |
.
.
之后我改用了java语言,采用正则表达式去解析json。由于java是字节码,运行速度已经发送了质的改变。将它编译成了跨平台jar包后,可以在多种设备上运行。在手机上跑,无需jre,以微乎其微的耗电量和ARM芯片占用率刷榜单。 请下载附件后 (把zip后缀改成jar即可运行):链接: https://pan.baidu.com/s/1qiEzR32fxyorm9SZGBUXVQ?pwd=345e
调用参数cwhgn.jar -u [用户名] -p [用户密码], 当用户名未注册时,程序会自动帮你注册。手机端建议使用ej 脚本运行。

[java实现]Main.java | package com.android.test; | | | | import java.io.BufferedReader; | | import java.io.InputStreamReader; | | import java.io.PrintWriter; | | import java.net.URL; | | import java.net.URLConnection; | | import java.util.regex.Matcher; | | import java.util.regex.Pattern; | | | | | | | | | | | | | | public class Main | | { | | private static final String REGU_URL = "http://www.codetiger.win/extra/index.php"; | | private static final String POST_URL = "http://www.codetiger.win/extra/API.php"; | | private static final int MAX_ARRAY_SIZE = 5040; | | private static boolean[] markPmArray = new boolean[MAX_ARRAY_SIZE]; | | | | private static final Pattern reCode = Pattern.compile("\\{\\\"code\\\":(\\d+)"); | | private static final Pattern re = Pattern.compile("\\{\\\"code\\\":(\\d+),\\\"A\\\":(\\d+),\\\"B\\\":(\\d+),\\\"count\\\":(\\d+),\\\"tokens\\\":\\\"(\\d+)\\\"\\}"); | | private static ResponseJson responseJson = new ResponseJson(); | | | | public static void main(String[] args) | | { | | if(args.length !=4 || !args[0].equals("-u") || !args[2].equals("-p")) | | { | | System.out.println("Usage: java -jar cwhgn.jar -u [userName] -p [passWord]"); | | System.exit(1); | | } | | | | String userName = args[1]; | | String userPassword = args[3]; | | | | String responseString = sendPost(POST_URL, "send=answer&number=0123&username=" + userName + "&password=" + userPassword).toString(); | | Matcher m = reCode.matcher(responseString); | | if(m.find()) | | { | | if(Integer.parseInt(m.group(1)) == 300) | | { | | int regRet = regUser(userName, userPassword); | | if(regRet != 100) | | { | | System.out.printf("The userName '%s' has been registered or the userPassword '%s' is wrong!\n", userName, userPassword); | | System.exit(1); | | } | | } | | } | | else | | { | | System.out.println("Please try again!"); | | System.exit(1); | | } | | | | String[] pmArray = getPermutations(); | | int pmArrayLen = pmArray.length; | | | | long startMilis=System.currentTimeMillis(); | | long guessScore=0; | | long guessSpeed=0; | | | | while (true) | | { | | int currentIndex = 0; | | long responseTokens = -1; | | int guessTimes = 0; | | | | for(int i=0; i<MAX_ARRAY_SIZE; i++) | | { | | markPmArray[i] = true; | | } | | | | while (true) | | { | | try | | { | | responseString = sendPost(POST_URL, "send=answer&username=" + userName + "&password=" + userPassword + "&number="+ pmArray[currentIndex]).toString(); | | m = re.matcher(responseString); | | if(! m.find()) | | { | | System.out.println("Received data failed!"); | | continue; | | | | } | | responseJson.getJson(Integer.parseInt(m.group(1),10), Integer.parseInt(m.group(2),10), Integer.parseInt(m.group(3),10), Integer.parseInt(m.group(4),10), Long.parseLong(m.group(5))); | | } | | catch (Exception e) | | { | | continue; | | | | } | | | | if(guessScore == 0) | | { | | guessScore = responseJson.count; | | } | | | | guessTimes ++; | | | | if(responseJson.A == 4) | | { | | if(System.currentTimeMillis()-startMilis > 6000) | | { | | guessSpeed = (responseJson.count - guessScore); | | guessScore = responseJson.count; | | startMilis = System.currentTimeMillis(); | | } | | | | System.out.printf("Takes:[%d cycles], Answer:%s, Score:[%d +%d/min]\n", guessTimes, pmArray[currentIndex], responseJson.count, guessSpeed*10); | | break; | | } | | | | if(responseTokens == -1) | | { | | responseTokens = responseJson.tokens; | | } | | else if(responseTokens != responseJson.tokens) | | { | | System.out.println("Reset ..."); | | break; | | } | | | | currentIndex = guessCore(pmArray, pmArrayLen, responseJson.A*5+responseJson.B, pmArray[currentIndex]); | | } | | } | | } | | | | private static int regUser(String userName, String userPassword) | | { | | String responseString = sendPost(REGU_URL, "send=reg&qq=123456789&username=" + userName + "&password="+ userPassword).toString(); | | Matcher m = reCode.matcher(responseString); | | return (m.find()) ?(Integer.parseInt(m.group(1), 10)) :0; | | } | | | | private static int getWeights(String correctNum, String guessNum) | | { | | int retWeights = 0; | | for(int i=0; i<4; i++) | | { | | int digitalPosition = guessNum.indexOf((correctNum.substring(i, i+1))); | | if(digitalPosition != -1) | | { | | retWeights += (digitalPosition==i)?5:1; | | } | | } | | return retWeights; | | } | | | | private static int guessCore(String[] inputPmArray, int inputPmArrayLen, int responseWeights, String guessNum) | | { | | int markIndex = 0; | | for(int i=0; i<inputPmArrayLen; i++) | | { | | if(markPmArray[i]) | | { | | if(getWeights(inputPmArray[i], guessNum) != responseWeights) | | { | | markPmArray[i] = false; | | } | | else if(markIndex == 0) | | { | | markIndex = i; | | } | | } | | } | | return markIndex; | | } | | | | private static String[] getPermutations() | | { | | String[] pmArray = new String[MAX_ARRAY_SIZE]; | | int index=0; | | for(int i=0; i<10; i++) | | for(int j=0; j<10; j++) | | for(int k=0; k<10; k++) | | for(int l=0; l<10; l++) | | { | | if((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l)!=0) | | { | | pmArray[index++]= "" + i + j + k + l; | | } | | | | } | | return pmArray; | | } | | | | public static StringBuffer sendPost(String postURL, String postData) | | { | | PrintWriter pWriter = null; | | BufferedReader bReader = null; | | StringBuffer sBuffer = new StringBuffer(""); | | | | try | | { | | URL realUrl = new URL(postURL); | | URLConnection conn = realUrl.openConnection(); | | | | conn.setRequestProperty("accept", "*/*"); | | conn.setRequestProperty("connection", "keep-alive"); | | conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); | | conn.setDoOutput(true); | | conn.setDoInput(true); | | | | pWriter = new PrintWriter(conn.getOutputStream()); | | pWriter.print(postData); | | pWriter.flush(); | | | | bReader = new BufferedReader(new InputStreamReader(conn.getInputStream())); | | | | String line = null; | | while ((line = bReader.readLine()) != null) | | { | | sBuffer.append(line); | | } | | } | | catch (Exception e) | | { | | System.out.println("An exception occurred while sending a POST request!"+e); | | } | | finally | | { | | try | | { | | pWriter.close(); | | bReader.close(); | | } | | catch (Exception e) | | { | | | | } | | } | | return sBuffer; | | } | | | | protected static class ResponseJson | | { | | int code, A, B, count; | | long tokens; | | void getJson(int inputCode, int inputA, int inputB, int inputCount, long inputTokens) | | { | | this.code = inputCode; | | this.A = inputA; | | this.B = inputB; | | this.count = inputCount; | | this.tokens = inputTokens; | | } | | } | | }COPY |
.
.
用其他语言的实现,思路基本相同,就当复习语法。
>>
[vbs版] | | | | | | | Dim markPM(5040) | | GuessNumber "adad", "123", "http://www.codetiger.win/extra/API.php" | | | | | | Function GetPermutations() | | Dim retArray(5040), index | | index = 0 | | For i = 0 To 9 | | For j = 0 To 9 | | For k = 0 To 9 | | For l = 0 To 9 | | If ((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l)) <> 0 Then | | retArray(index) = i & j & k & l & "" | | index = index + 1 | | End If | | Next | | Next | | Next | | Next | | GetPermutations = retArray | | End Function | | | | Function GetWeights(correctNum, guessNum) | | Dim retWeights | | retWeights = 0 | | For i = 1 To 4 | | For j = 1 To 4 | | If Mid(correctNum, i, 1) = Mid(guessNum, j, 1) Then | | If i = j Then | | retWeights = retWeights + 5 | | Else | | retWeights = retWeights + 1 | | End If | | End If | | Next | | Next | | GetWeights = retWeights | | End Function | | | | Function GuessCore(arrayPM, arrayPMLen, responseWeights, guessIndex) | | Dim markIndex | | markIndex = -1 | | For i = 0 To arrayPMLen-1 | | If markPM(i) Then | | If GetWeights(arrayPM(i), arrayPM(guessIndex)) <> responseWeights Then | | markPM(i) = False | | ElseIf i <> guessIndex And markIndex = -1 Then | | markIndex = i | | End If | | End If | | Next | | GuessCore = markIndex | | End Function | | | | Function HttpPostData(hostURL, postString) | | Dim respJson | | With CreateObject("MSXML2.XMLHTTP") | | .Open "POST", hostURL, False | | .setRequestHeader "CONTENT-TYPE", "application/x-www-form-urlencoded" | | .setRequestHeader "CONNECTION", "Keep-Alive" | | .send postString | | respJson = .responseText | | End With | | HttpPostData = Split(replace(respJson, ":", ","), ",") | | End Function | | | | Function GuessNumber(userName, passWord, hostURL) | | Dim pmArray, pmArrayLen | | Dim startMilis, guessScore, guessSpeed | | startTime = Timer : guessScore = 0 : guessSpeed = 0 | | | | pmArray = GetPermutations() | | pmArrayLen = Ubound(pmArray) | | | | Do | | Dim nIndex, responseTokens, respData, guessTimes | | responseString="" : nIndex=0 : responseTokens="" : espData="": guessTimes=0 | | | | For i = 0 To pmArrayLen-1 | | markPM(i) = True | | Next | | | | Do | | respData = HttpPostData(hostURL, "username=" & userName & "&password=" & passWord & "&send=answer&number=" & pmArray(nIndex)) | | If Ubound(respData) + 1 <> 10 Then | | WScript.echo "Requests error!!!'" | | Exit Do | | End If | | | | If guessScore = 0 Then | | guessScore = respData(7) | | End If | | | | guessTimes = guessTimes + 1 | | | | If respData(3) = "4" Then | | If Timer - startTime > 6 Then | | guessSpeed = (CLng(respData(7)) - guessScore)*10 | | guessScore = CLng(respData(7)) | | startTime = Timer | | End If | | WScript.echo "Takes:[" & guessTimes & "th], Answer:" & pmArray(nIndex) & ", Score:[" & respData(7) & " +" & guessSpeed & "/min]" | | Exit Do | | End If | | | | If responseTokens = "" Then | | responseTokens = respData(9) | | ElseIf responseTokens <> respData(9) Then | | WScript.echo "Reset..." | | Exit Do | | End If | | | | nIndex = GuessCore(pmArray, pmArrayLen, CInt(respData(3))*5+CInt(respData(5)), nIndex) | | If nIndex = -1 Then | | WScript.echo "Fault..." | | Exit Do | | End If | | Loop | | Loop | | End FunctionCOPY |
>>
[js混编]效率还不错 | 1>1 | | | | | | | | | | | | var USER_NAME='adad'; | | var PASS_WORD='123'; | | var POST_URL ='http://www.codetiger.win/extra/API.php'; | | | | var markPM=[]; | | guessNumber(USER_NAME, PASS_WORD, POST_URL); | | | | | | function getPermutations() | | { | | var retArray=[]; | | for(var i=0; i<10; i++) | | for(var j=0; j<10; j++) | | for(var k=0; k<10; k++) | | for(var l=0; l<10; l++) | | if((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l)) | | retArray.push('' + i + j + k + l); | | return retArray; | | } | | | | function getWeights(correctNum, guessNum) | | { | | var retWeights = 0; | | var gArray=guessNum.split(''); | | for(var i=0; i<4; i++) | | { | | var dIndex=correctNum.indexOf( gArray[i]); | | if(dIndex != -1) | | { | | retWeights += (dIndex==i)?5:1; | | } | | } | | return retWeights; | | } | | | | function guessCore(arrayPM, arrayPMLen, responseWeights, guessNum) | | { | | var markIndex = -1; | | for(var i=1; i<arrayPMLen; i++) | | { | | if(markPM[i]) | | { | | if(getWeights(arrayPM[i], guessNum) != responseWeights) | | { | | markPM[i] = false; | | } | | else if(markIndex == -1) | | { | | markIndex = i; | | } | | } | | } | | return markIndex; | | } | | | | function httpPostData(hostURL, postString) | | { | | var xmlHTTP=new ActiveXObject('Msxml2.XMLHTTP'); | | xmlHTTP.open('POST', hostURL, false); | | xmlHTTP.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); | | xmlHTTP.setRequestHeader('Connection', 'Keep-Alive'); | | xmlHTTP.send(postString); | | | | if(xmlHTTP.readyState === 4) | | { | | if( | | ( | | (xmlHTTP.status >= 200) && | | (xmlHTTP.status < 300) | | ) || | | ( | | (xmlHTTP.status == 304) | | ) | | ) | | { | | return eval( '(' + xmlHTTP.responseText + ')' ); | | } | | else | | { | | return null | | } | | } | | } | | | | function guessNumber(userName, passWord, hostURL) | | { | | var pmArray=getPermutations(); | | var pmArrayLen=pmArray.length; | | var startMilis=new Date(), guessScore=0, guessSpeed=0; | | | | for(;;) | | { | | var currentIndex=0, responseTokens=null, respData=null, guessTimes=0; | | | | for(var i=0; i<pmArrayLen; i++) | | { | | markPM[i] = true; | | } | | | | for(;;) | | { | | try | | { | | respData = httpPostData(hostURL, 'username=' + userName + '&password=' + passWord + '&send=answer&number=' + pmArray[currentIndex]); | | if(respData == null) | | { | | continue; | | } | | } | | catch(e) | | { | | WScript.echo('Requests error!!!'); | | break; | | } | | | | | | if(guessScore == 0) | | { | | guessScore = respData['count']; | | } | | | | guessTimes ++; | | | | if(respData['A'] == 4) | | { | | if(new Date()-startMilis > 6000) | | { | | guessSpeed=(respData['count'] - guessScore)*10; | | guessScore=respData['count']; | | startMilis=new Date(); | | } | | WScript.echo('Takes:[' + guessTimes + 'th], Answer:' + pmArray[currentIndex] + ', Score:[' + respData['count'] + ' +' + guessSpeed + '/min]'); | | break; | | } | | | | if(responseTokens == null) | | { | | responseTokens = respData['tokens']; | | } | | else if(responseTokens != respData['tokens']) | | { | | WScript.echo('Reset...'); | | break; | | } | | | | if( (currentIndex=guessCore(pmArray, pmArrayLen, respData['A']*5+respData['B'], pmArray[currentIndex])) == -1) | | { | | WScript.echo('Fault...'); | | break; | | } | | } | | } | | }COPY |
>>
[python版] py3标准 | | | import requests | | import itertools | | | | | | userNAMZE='adad' | | passWORD='123' | | | | | | hostURL='http://www.codetiger.win/extra/API.php' | | | | | | | | markPM=[] | | | | | | def GetWeights(correctNum, guessNum): | | retWeights=0 | | for i in range(0,4): | | for j in range(0,4): | | if correctNum[i] == guessNum[j] : | | if i==j : | | retWeights += 5 | | else: | | retWeights += 1 | | return retWeights | | | | | | def GuessCore(arrayPM, arrayLen, responseWeights, guessNum): | | markIndex=None | | for i in range(0, arrayPMLen): | | if markPM[i]: | | if GetWeights(arrayPM[i], guessNum) != responseWeights : | | markPM[i]=False | | elif markIndex == None : | | markIndex=i | | if markIndex==None : | | markIndex=0 | | return markIndex | | | | | | if __name__ == "__main__": | | | | | | arrayPM=[] | | for r in itertools.permutations('0123456789', 4): | | arrayPM.append(''.join(r)) | | | | | | arrayPMLen = len(arrayPM) | | | | | | markPM=[False]*arrayPMLen | | | | | | while True: | | | | | | for i in range(0, arrayPMLen): | | markPM[i]=True | | | | | | currentIndex=0 | | | | | | guessTimes=0 | | | | | | responseTokens=None | | | | | | while True: | | | | | | try: | | r = requests.post(hostURL, {'password':passWORD, 'username':userNAMZE, 'number':arrayPM[currentIndex], 'send':'answer'}).json() | | except: | | print("Requests error!!!") | | break | | | | | | guessTimes += 1 | | | | | | if r['A'] == 4 : | | print("Takes {0} times: {1}".format(guessTimes, arrayPM[currentIndex])) | | break | | | | | | if responseTokens == None: | | responseTokens = r['tokens'] | | | | | | elif responseTokens != r['tokens'] : | | print("Reset...") | | break | | | | | | currentIndex = GuessCore(arrayPM, arrayPMLen, r['A']*5+r['B'], arrayPM[currentIndex])COPY |
>>
[C语言版]cfree编译 | #include <stdio.h> | | #include <stdbool.h> | | #include <string.h> | | #include <windows.h> | | #include <winsock2.h> | | #include <time.h> | | | | | | #define USER_NAME "adad" | | #define PASS_WORD "123" | | | | | | #define POST_HEAD "\ | | POST /extra/API.php HTTP/1.1\r\n\ | | TE: deflate,gzip;q=0.3\r\n\ | | Connection: Keep-Alive\r\n\ | | Host: www.codetiger.win\r\n\ | | Content-Length: 50\r\n\ | | Content-Type: application/x-www-form-urlencoded\r\n\ | | \r\n" | | | | | | | | #define MAX_POST_SIZE 512 | | #define MAX_ARRAY_SIZE 5040 | | | | | | #define RECEIVE_SIZE 512 | | #define SEND_SIZE 512 | | | | | | static char sendBuf[MAX_POST_SIZE] = POST_HEAD "username="USER_NAME "&password="PASS_WORD "&send=answer&number="; | | | | static int sendbuf_JSON_NUMBER_OFFSET; | | | | | | static char pmArray[MAX_ARRAY_SIZE][4]; | | | | static bool markPM[MAX_ARRAY_SIZE]= {false}; | | | | | | typedef struct{ | | int A; | | int B; | | int count; | | long long tokens; | | } RESPJSON, *PRESPJSON; | | | | | | int ParseReceiveBuf(PRESPJSON pRespJson, const char* receiveBuf) | | { | | int ret = 0; | | char* p = NULL; | | | | ((p=strstr(receiveBuf, "\"A\":")) != NULL)? (pRespJson->A = atoi(p+4)) :(ret=1); | | ((p=strstr(receiveBuf, "\"B\":")) != NULL)? (pRespJson->B = atoi(p+4)) :(ret=1); | | ((p=strstr(receiveBuf, "\"count\":")) != NULL)? (pRespJson->count = atoi(p+8)) :(ret=1); | | ((p=strstr(receiveBuf, "\"tokens\":")) != NULL)? (pRespJson->tokens = atoll(p+10)) :(ret=1); | | | | return ret; | | } | | | | | | int InitpmArray() | | { | | int i, j, k, l, index=0; | | | | for(i=0; i<10; i++) | | for(j=0; j<10; j++) | | for(k=0; k<10; k++) | | for(l=0; l<10; l++) | | { | | if((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l)) | | { | | pmArray[index][0] = i+'0'; | | pmArray[index][1] = j+'0'; | | pmArray[index][2] = k+'0'; | | pmArray[index][3] = l+'0'; | | index ++; | | } | | } | | | | return 0; | | } | | | | | | int GetWeights(char* correctNum, char* guessNum) | | { | | int i, j, retWeights = 0; | | | | for(i=0; i<4; i++) | | for(j=0; j<4; j++) | | { | | if (correctNum[i] == guessNum[j]) | | { | | retWeights += (i==j)?5:1; | | } | | } | | | | return retWeights; | | } | | | | | | int GuessCore(int responseWeights, int currentIndex) | | { | | int i, markIndex = -1; | | for(i=0; i<MAX_ARRAY_SIZE; i++) | | { | | if(markPM[i]) | | { | | if(GetWeights(pmArray[i], pmArray[currentIndex]) != responseWeights) | | { | | markPM[i] = false; | | } | | else if( (markIndex <i ) && (i != currentIndex) ) | | { | | markIndex = i; | | } | | } | | } | | return markIndex; | | } | | | | | | int GuessNumber(struct sockaddr_in sAddr) | | { | | | | InitpmArray(); | | | | | | long long responseTokens; | | int currentIndex, guessTimes; | | | | | | char receiveBuf[RECEIVE_SIZE]; | | | | | | RESPJSON respJson={0}, *pRespJson = &respJson; | | | | | | SOCKET uintScoket; | | | | for(;;) | | { | | | | memset(markPM, true, MAX_ARRAY_SIZE); | | | | | | currentIndex =2519, guessTimes =0, responseTokens =-1; | | | | for(;;) | | { | | | | strncpy(sendBuf+sendbuf_JSON_NUMBER_OFFSET, pmArray[currentIndex], 4); | | | | | | if((uintScoket = socket(AF_INET,SOCK_STREAM,0)) < 0) | | { | | fprintf(stderr, "Socket error!\n"); | | break; | | } | | | | | | if(connect(uintScoket,(const struct sockaddr*)&sAddr,sizeof(sAddr)) < 0) | | { | | fprintf(stderr, "Connet error!\n"); | | break; | | } | | | | | | if(send(uintScoket,sendBuf,SEND_SIZE,0) < 0) | | { | | fprintf(stdout, "Send error!!!\n"); | | break; | | } | | | | | | int respINT = -1; | | if((respINT = recv(uintScoket,receiveBuf,RECEIVE_SIZE,0)) < 0) | | { | | fprintf(stdout, "Receive error!!!\n"); | | break; | | } | | | | | | closesocket(uintScoket); | | | | | | if(ParseReceiveBuf(pRespJson,receiveBuf) == 1){ | | fprintf(stdout, "Parse json failed!\n"); | | break; | | } | | | | | | guessTimes ++; | | | | | | if(pRespJson->A == 4) | | { | | fprintf(stdout, "=======Takes:%dth, Number:%-4.4s, Score:%d\n", guessTimes, pmArray[currentIndex], pRespJson->count); | | break; | | } | | | | | | if(responseTokens == -1) | | { | | responseTokens = pRespJson->tokens; | | } | | else if(responseTokens != pRespJson->tokens) | | { | | fprintf(stdout, "Reset...\n"); | | break; | | } | | | | | | if((currentIndex=GuessCore(pRespJson->A*5+pRespJson->B, currentIndex)) == -1) | | { | | fprintf(stdout, "Error!!!\n"); | | break; | | } | | } | | } | | return 0; | | } | | | | | | int main() | | { | | | | srand((unsigned)time(NULL)); | | | | | | sendbuf_JSON_NUMBER_OFFSET = strlen(sendBuf); | | | | | | WSADATA wsData; | | if(WSAStartup(MAKEWORD(2, 1), &wsData) !=0) | | { | | fprintf(stderr, "Starting the winsocket failed\n"); | | exit(1); | | } | | | | | | struct sockaddr_in sAddr={0}; | | sAddr.sin_family = AF_INET; | | sAddr.sin_port = htons(80); | | sAddr.sin_addr.S_un.S_addr = inet_addr("43.240.12.145"); | | | | | | GuessNumber(sAddr); | | | | | | WSACleanup(); | | return 0; | | }COPY |
>>
[C#版]写起来真啰嗦,还需要.NET3.5及以上。 | | | | | | | | | | | | | | | | | | | using System; | | using System.Net; | | using System.IO; | | using System.Text; | | using System.Xml; | | using System.Runtime.Serialization.Json; | | using System.Runtime.Serialization; | | using System.Text.RegularExpressions; | | | | namespace GuessNumApplication | | { | | public class MainProgram | | { | | static void Main(string[] args) | | { | | GuessObj guessObj = new GuessObj("adad", "123", "http://www.codetiger.win/extra/API.php"); | | } | | } | | | | public class RespData | | { | | public long tokens{get; set;} | | public int A{get; set;} | | public int B{get; set;} | | public int count{get; set;} | | } | | | | public class GuessObj | | { | | private static readonly int MAX_ARRAY_SIZE = 5040; | | private bool[] markPM = new bool[MAX_ARRAY_SIZE]; | | | | public GuessObj(string userName, string passWord, string hostURL) | | { | | GuessNumber(userName, passWord, hostURL); | | } | | | | private string[] Permutations() | | { | | string[] pmArray = new string[MAX_ARRAY_SIZE]; | | int index=0; | | for(int i=0; i<10; i++){ | | for(int j=0; j<10; j++){ | | for(int k=0; k<10; k++){ | | for(int l=0; l<10; l++){ | | if((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l)!=0){ | | pmArray[index++] = "" + i + j + k + l; | | } | | } | | } | | } | | } | | return pmArray; | | } | | | | private int GetWeights(string correctNum, string guessNum) | | { | | int retWeights = 0; | | for(int i=0; i<4; i++){ | | for(int j=0; j<4; j++){ | | if (correctNum[i] == guessNum[j]) { | | retWeights += (i==j)?5:1; | | } | | } | | } | | return retWeights; | | } | | | | private int GuessCore(string[] arrayPM, int arrayPMLen, int responseWeights, string guessNum) | | { | | int markIndex = -1; | | for(int i=1; i<arrayPMLen; i++){ | | if(markPM[i]){ | | if(GetWeights(arrayPM[i], guessNum) != responseWeights){ | | markPM[i] = false; | | }else if(markIndex == -1){ | | markIndex = i; | | } | | } | | } | | return markIndex; | | } | | | | private object ParseJson(string strJson) | | { | | DataContractJsonSerializer dJsonSerializer = new DataContractJsonSerializer(typeof(RespData)); | | MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(strJson)); | | return dJsonSerializer.ReadObject(memoryStream); | | } | | | | private string HttpPostData(string url, string postStr) | | { | | var httpWebRequest = (HttpWebRequest)WebRequest.Create(url); | | httpWebRequest.ContentType = "application/x-www-form-urlencoded"; | | httpWebRequest.Method = "POST"; | | | | using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) | | { | | streamWriter.Write(postStr); | | streamWriter.Flush(); | | streamWriter.Close(); | | } | | | | var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); | | using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) | | { | | return streamReader.ReadToEnd(); | | } | | } | | | | private void GuessNumber(string userName, string passWord, string hostURL) | | { | | string[] pmArray = Permutations(); | | int pmArrayLen = pmArray.Length; | | | | RespData respData = new RespData(); | | | | for(;;){ | | string responseString = ""; | | int currentIndex = 0; | | long? responseTokens = null; | | int guessTimes = 0; | | | | for(int i=0; i<MAX_ARRAY_SIZE; i++){ | | markPM[i] = true; | | } | | | | for(;;){ | | try{ | | responseString = HttpPostData(hostURL, "username="+userName + "&password="+passWord + "&send=answer" + "&number="+pmArray[currentIndex]); | | respData =ParseJson(responseString) as RespData; | | }catch{ | | Console.WriteLine("Requests error!!!"); | | break; | | } | | | | guessTimes ++; | | | | if(respData.A == 4){ | | Console.WriteLine("Takes:{0}th, Number:{1}, Score:{2}", guessTimes, pmArray[currentIndex], respData.count); | | break; | | } | | | | if(responseTokens == null){ | | responseTokens = respData.tokens; | | }else if(responseTokens != respData.tokens){ | | Console.WriteLine("Reset..."); | | break; | | } | | | | if( (currentIndex=GuessCore(pmArray, pmArrayLen, respData.A*5+respData.B, pmArray[currentIndex])) == -1){ | | Console.WriteLine("Fault..."); | | break; | | } | | } | | } | | } | | } | | }COPY |
>>
[php猜数字服务端实现]可用它在本地模拟猜数字游戏。 | <?php | | header("Cache-Control: no-cache, must-revalidate"); | | | | function digital4s_rand(){ | | $rdigital = array(); | | while ($i<4) { | | $rdigital[] = mt_rand(0, 9); | | $rdigital = array_flip(array_flip($rdigital)); | | $i = count($rdigital); | | } | | shuffle($rdigital); | | return implode('', $rdigital); | | } | | | | if ($_POST['send'] == 'answer') { | | if (!empty($_POST['number'])) { | | $inputNumber = (string)$_POST['number']; | | | | $json=Json_decode(file_get_contents("server.sdb"),true); | | | | $count=$json['count']; | | $tokens=$json['tokens']; | | $correctNumber =$json['number']; | | | | $A=0; $B=0; | | for ($i=0; $i<4; $i++) { | | for ($j=0; $j<4; $j++) { | | if ($inputNumber[$i] === $correctNumber[$j]){ | | ($i==$j) ?$A++ :$B++; | | } | | } | | } | | | | if($A == 4){ | | $json['number'] = digital4s_rand(); | | $json['tokens'] = (string)mt_rand(100000000, 200000000); | | $json[ 'count'] = $count + 1; | | file_put_contents("server.sdb",json_encode($json)); | | } | | } | | die(json_encode(array("code"=>200, "A"=>$A, "B"=>$B, "count"=>$json['count'], "tokens"=>$tokens))); | | }else{ | | ?> | | | | <html> | | <head> | | <title>phpinfo</title> | | <meta http-equiv="content-type" content="text/html;charset=utf-8"> | | | | <style type="text/css"> | | body { | | background-color: #fff; | | color: #222; | | font-family: sans-serif; | | } | | pre { | | margin: 0; | | font-family: monospace; | | } | | a:hover { | | text-decoration: underline; | | } | | table { | | border-collapse: collapse; | | border: 0; | | width: 934px; | | box-shadow: 1px 2px 3px #0D2B2D; | | } | | .center {text-align: center;} | | .center table {margin: 1em auto; text-align: left;} | | .center th {text-align: center !important;} | | td, th { | | border: 1px solid #666; | | font-size: 100%; | | vertical-align: baseline; | | padding: 4px 5px; | | } | | h1 {font-size: 150%;} | | h2 {font-size: 125%;} | | .p {text-align: left;} | | .e { | | background-color: #AAC1D4; | | width: 300px; | | font-weight:normal; | | } | | .h { | | background-color: #AAC1D4; | | font-weight: normal; | | } | | .alink{ | | color: #000000; | | text-decoration: none; | | } | | .v { | | background-color: #ddd; | | max-width: 300px; | | overflow-x: auto; | | } | | .v i {color: #999;} | | img {display:none;} | | hr { | | width: 934px; | | background-color: #ccc; | | border: 0; | | height: 1px; | | } | | </style> | | </head> | | | | <body> | | <h1>APMA</h1> | | <table style="width:365px;background-color: #AAC1D4;> | | <tr class="h"> | | <td> | | <a class="alink" href="expand.php">APMA<br>Expand Information</a> | | </td> | | <td> | | <a class="alink" href="adminer">Adminer<br>Database Manager</a> | | </tr> | | </table> | | <?php | | ob_start(); | | phpinfo(); | | $i = ob_get_contents(); | | ob_end_clean(); | | echo ( str_replace ( "module_Zend Optimizer", "module_Zend_Optimizer", preg_replace ( '%^.*<body>(.*)</body>.*$%ms', '$1', $i ) ) ) ; | | ?> | | </body> | | </html> | | <?php }?>COPY |
|