返回列表 发帖

[其他] 批处理及多种语言实现 CWHGN猜数字

CWHGN猜数字具体要求请参见帖子   http://www.bathome.net/thread-44826-1-2.html

我先用看似单纯的批处理去实现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 ('cscript -nologo -e:jscript "%~f0" "%POST_URL%" "%USER_NAME%" "%PASS_WORD%" !GUESS_NUMBER!') do (
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('Msxml2.XMLHTTP');
xmlHTTP.open('SEND', WScript.arguments(0) + '?username=' + WScript.arguments(1) + '&password=' + WScript.arguments(2) + '&send=answer&number=' + WScript.arguments(3), false);
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;
/**
* @author Happy from Bathome
* @time
*/
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;
//break;
}
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;
//break;
}
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)
{
// TODO: handle exception
}
}
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版]
'&@echo off&cls&cscript -nologo -e:vbscript "%~f0" %*&pause&exit /b
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
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/* :
@echo off
cscript -nologo -e:jscript "%~f0" %*
pause&exit /b
*/
/********************** MAIN PROCESS ***********************/
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标准
# -*- coding:utf-8 -*-
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__":
# 生成由[0-9]构成的4位全排列数
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
# 重置tokens
responseTokens=None
#内层循环猜测
while True:
# 提交数字,返回json格式
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
# 如果tokens为空更新tokens
if responseTokens == None:
responseTokens = r['tokens']
# 如果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
//定义SCOKET收发阈值
#define RECEIVE_SIZE   512
#define SEND_SIZE      512
//POST 发送容器
static char sendBuf[MAX_POST_SIZE] = POST_HEAD  "username="USER_NAME  "&password="PASS_WORD  "&send=answer&number=";
//Json number开始索引
static int sendbuf_JSON_NUMBER_OFFSET;
//数组pmArray
static char pmArray[MAX_ARRAY_SIZE][4];
//筛法标记数组
static bool markPM[MAX_ARRAY_SIZE]= {false};
//返回Json结构体
typedef struct{
int A;
int B;
int count;
long long tokens;
} RESPJSON, *PRESPJSON;
//ParseReceiveBuf Json解析函数
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;
}
//初始化数组pmArray,生成4位全排列
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)
{
//初始化数组pmArray,生成4位全排列
InitpmArray();
//声明参数、计数器
long long responseTokens;
int currentIndex, guessTimes;
//POST返回结构接收容器
char receiveBuf[RECEIVE_SIZE];
//Json返回结构体
RESPJSON respJson={0}, *pRespJson = &respJson;
//声明安全套接口
SOCKET uintScoket;
for(;;)
{
//重置布尔标记数组
memset(markPM, true, MAX_ARRAY_SIZE);
//重置各类参数、计数器
currentIndex =2519/*rand()%MAX_ARRAY_SIZE*/, guessTimes =0, responseTokens =-1;
for(;;)
{
//装入猜测数字 pmArray[currentIndex]
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;
}
//POST发送
if(send(uintScoket,sendBuf,SEND_SIZE,0) < 0)
{
fprintf(stdout, "Send error!!!\n");
break;
}
//POST接收
int respINT = -1;
if((respINT = recv(uintScoket,receiveBuf,RECEIVE_SIZE,0)) < 0)
{
fprintf(stdout, "Receive error!!!\n");
break;
}
//关闭安全套接口
closesocket(uintScoket);
//解析POST返还信息
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;
}
//判断tokens重置
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;
}
//------ MAIN 主函数 ------
int main()
{
//初始化随机种子
srand((unsigned)time(NULL));
//获取Json number 开始索引
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及以上。
/*************************************************************************
@ECHO OFF&CLS&TITLE MINI CSHARP COMPILER BY HAPPY
for /f "delims=" %%a in ('dir /a-d /b /s "%systemroot%\Microsoft.NET\Framework\v3.5\csc.exe"') do (
"%%~a" /out:a.exe "%~f0" && a.exe
pause&exit/b
)
)
set/p=You needs Microsoft.NET!&exit/b
**************************************************************************/
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
3

评分人数

我还活着,回归时间未知 数独计划延期[有点事情]
猜数坏了,暂时修不了【可能代码不严谨产生的复制问题】

TOP

回复 2# bbaa


    发现窥屏er x1

TOP

回复 2# bbaa
ok,收到,延期不要紧,只要有创新就好玩。

TOP

回复 3# 老刘1号
小站有私货,不错。

TOP

回复 5# happy886rr


    感谢支持,偶尔发些小作品

TOP

66666
adad       66666 + 0     0.0/min
vic3       54761 + 0     0.0/min
coadsa       839 + 0     0.0/min
llsd         139 + 0     0.0/min
sfwfssf        0 + 0     0.0/minCOPY
[url=][/url]

TOP

回复 7# 523066680
一起6

TOP

本帖最后由 523066680 于 2017-8-10 21:56 编辑

回复 8# happy886rr

一、
    我还在折腾那个树的生成,但是遇到一些问题,
方案和百科中的 “反馈个数指标” 方案类似,但是平均猜数次数和里面的统计结果不同,懵逼了,还在排查。
times: 26991, rate: 5.355357
$times_elements = {
  '1' => 1,
  '5' => 1993,
  '8' => 12,
  '6' => 1879,
  '7' => 390,
  '3' => 109,
  '2' => 13,
  '4' => 643
};COPY
百度统计的是 5.308,每种回合数的统计也不一样

=================================
二、
如果不使用结构树,每次都遍历筛选,哪怕是索引操作,消耗也蛮大的,我写的C,测完5040种情况,去掉printf, 需要2.8秒。

=================================
三、
同样是筛选法,同样是5040种情况去测试,以不同的起点开始,平均回合数是不一样的。
0123 -> 5.560317
6789 -> 5.593254
不过,这大概和筛选数组后选取不同起点的区别类似。比如选择筛选后的最后一个、第一个排列,结果是不一样的。
[url=][/url]

TOP

本帖最后由 happy886rr 于 2017-8-10 22:39 编辑

回复 9# 523066680
我觉得要缩小数组的规模去筛选。
可以使用位筛法。这样降到5040/8的小规模,然后C语言的内存读取就会加快。效率就上去了。

TOP

本帖最后由 523066680 于 2017-8-11 19:19 编辑

批处理的话可以用这种方式(借wget 或者curl)获取返回值
wget -O res.txt "http://www.codetiger.win/extra/API.php?username=***&password=***&number=1234&send=answer"COPY
返回示例:res.txt
{"code":150,"A":0,"B":1,"count":141878,"tokens":"6257936998656230"}

搜索树也可以用类似哈希的方式,事先初始化一系列变量,
TREE[0123][01]=0124
TREE[ORDER1][AB1][ORDER2][AB2]=...

这样的话处理过程就像是查表法。但是终究无力再写批处理,罢了。
[url=][/url]

TOP

最后手痒还是写了,像这样:

struct.bat
@echo off
set tree=0123
set tree[0123][04]=1032
set tree[0123][04][1032][04]=2301
set tree[0123][04][1032][04][2301][22]=2310
set tree[0123][04][1032][04][2301][22][2310][04]=3201
set tree[0123][04][1032][04][2301][04]=3210
set tree[0123][04][1032][22]=1230
set tree[0123][04][1032][22][1230][13]=1302
set tree[0123][04][1032][22][1230][13][1302][04]=2031
set tree[0123][04][1032][22][1230][04]=3012
set tree[0123][21]=0134COPY
批处理调用 struct.bat 为变量赋值。借 wget 向网站 post 并获取反馈信息。
@echo off
setlocal enabledelayedexpansion
echo Tree building ...
call struct.bat
echo Begin ...
:AGAIN
    set guess=0123
    set varname=tree
    set prev=0
:WHILE
    call :post %guess%
    echo %guess% - %AB%, %tokens%
    if "%AB%" == "40" (
        echo "Success"
        goto :AGAIN
    )
    if not "%prev%" == "0" (
        if not "%prev%" == "%tokens%" (
            echo "tokens changed";
            goto :AGAIN
        )
    )
    set varname=%varname%[%guess%][%AB%]
    set guess=!%varname%!
    set prev=%tokens%
goto WHILE
:post
wget --quiet -O res.txt "http://www.codetiger.win/extra/API.php?username=BatchScript&password=batchscript&number=%1&send=answer" 2>nul
for /f "tokens=4,6,10 delims=:,}" %%a in (res.txt) do (
    set AB=%%a%%b
    set tokens=%%c
)
goto :eofCOPY
猜题速度(很慢,但是感觉好玩)
adad       193791 + 0     0.0/min
vic3       142669 + 0     0.0/min
coadsa       850 + 0     0.0/min
BatchScript   752 + 55    109.6/min
llsd         139 + 0     0.0/min
s**sdf      75 + 0     0.0/min
sfwfssf        0 + 0     0.0/minCOPY
完整的 struct.bat 和 猜数字批处理,已上传附件:
1

评分人数

[url=][/url]

TOP

本帖最后由 happy886rr 于 2017-8-11 20:53 编辑

回复 13# 523066680
批处理也只能查表了,因为5000次循环批处理就要好几秒。
你的思路完美的解决了批处理的效率问题,100/min已经是极限了,毕竟是批处理嘛。第三方调用也很耗时的。

TOP

支持一下
#&cls&@powershell "Invoke-Expression ([Io.File]::ReadAllText('%~0',[Text.Encoding]::UTF8))" &pause&exit

TOP

本帖最后由 523066680 于 2017-8-23 12:04 编辑

本着坚持不懈的精神,终于把平均指标也跑出来了……
Times: 26551, average: 5.268056
1, 1
2, 4
3, 59
4, 574
5, 2430
6, 1885
7, 87COPY
1

评分人数

[url=][/url]

TOP

返回列表