UWSCのStarsをUWSCにとかせる
UWSC公式掲示板に懐かしいゲームが再びあったので、今度はAIもどきにしてみた。
Stars - 懐かしいゲーム
Linersさん作のスクリプトです。
print acw(GETID(GET_LOGPRINT_WIN),,,240, 400) + " ★☆★ STARS ★☆★<#cr>" x = random(100) +1 for i = 1 to 7 g = input("あなたの予想は?") if g = x then break else print format(g, 3) + ":" + format("☆", 7 - logn(2, abs(x - g))) + "<#cr> あと" + (7-i) + "回" next if i = 8 then msgbox("残念!! 答えは " + x + " でした。") else msgbox("★☆お見事☆★ " + i + "回 で正解です。")
AIもどき
Starsのスクリプトが「Stars.uws」として
OPTION EXPLICIT CONST TRY_NUM = 100 CONST NUM_MAX = 100 CONST NUM_MIN = 1 CONST SCRIPT_NAME = "Stars.uws" EXEC(GET_UWSC_DIR + "\uwsc.exe " + GET_CUR_DIR + "\" + SCRIPT_NAME) DIM widLog = GETID("UWSC - " + SCRIPT_NAME, "TUScript.UnicodeClass") DIM res = FALSE, i, wid, num = NUM_MIN, log, a[3], pre = 0, j, widRes, b = 0 HASHTBL rs FOR i = 1 TO 7 wid = GETID("UWSC - " + SCRIPT_NAME, "TFInpBox.UnicodeClass") SetNum(wid, num) log = SPLIT(GETSTR(widLog, 1), "<#CR>") widRes = GETID("UWSC - " + SCRIPT_NAME, "TFmsgDlg.UnicodeClass") IFB widRes > -1 THEN res = (pre = 0 OR pre = LENGTH(log)) BREAK ENDIF pre = LENGTH(log) IF pre > 3 THEN log = log[pre - 3] ELSE log = "" rs[num] = LENGTH(log) - LENGTH(REPLACE(log, "☆", "")) + 1 num = GetNextNum(num, a, rs, i) NEXT IF res THEN MSGBOX("Clear! " + i + " : " + num) ELSE MSGBOX("Fail...") FUNCTION SetNum(wid, num) RESULT = FALSE DIM c = 1 WHILE GETSTR(wid) <> num AND c < TRY_NUM SLEEP(0.1) SENDSTR(wid, num, 1, TRUE) c = c + 1 WEND WHILE !CLKITEM(wid, "OK") AND c < TRY_NUM SLEEP(0.1) c = c + 1 WEND SLEEP(0.1) RESULT = TRUE FEND FUNCTION GetNextNum(num, var a[], var rs[], i) DIM j, b IFB i = 1 THEN num = NUM_MAX a[2] = 0 ELSE IFB i = 2 THEN a[3] = 1 IFB rs[a[2], HASH_VAL] > rs[num] THEN a[2] = 1; a[3] = 0 ENDIF b = 1 j = 1 ELSE FOR j = 0 TO 2 a[j] = a[j + 1] NEXT a[3] = i - 1 b = 0 j = 1 IFB rs[a[2], HASH_VAL] > rs[num] THEN a[3] = a[2]; a[2] = a[1] IFB rs[a[1], HASH_VAL] > rs[num] THEN j = -1 a[1] = i - 1 ELSEIF rs[a[1], HASH_VAL] = rs[num] THEN b = 1 IFB rs[a[3], HASH_KEY] > rs[a[1], HASH_KEY] THEN IFB rs[a[1], HASH_KEY] > num THEN j = -1 a[1] = i - 1 ELSE a[2] = i - 1 ENDIF ELSE IFB rs[a[1], HASH_KEY] > num THEN a[2] = i - 1 ELSE j = -1 a[1] = i - 1 ENDIF ENDIF ELSE a[2] = i - 1 ENDIF ELSEIF rs[a[2], HASH_VAL] = rs[num] THEN b = 1 IFB rs[a[2], HASH_KEY] > rs[a[1], HASH_KEY] THEN IFB rs[a[1], HASH_KEY] > num THEN a[3] = a[2]; a[2] = i - 1 ENDIF ELSE IFB rs[a[1], HASH_KEY] < num THEN a[3] = a[2]; a[2] = i - 1 ENDIF ENDIF ENDIF ENDIF num = INT(rs[a[3], HASH_KEY] - (rs[a[3], HASH_KEY] - rs[a[2], HASH_KEY]) / (rs[a[3], HASH_VAL] + rs[a[2], HASH_VAL] + b) * (rs[a[2], HASH_VAL] + b) * j + 0.5) IF num < NUM_MIN THEN num = NUM_MIN + (NUM_MIN - num) IF num > NUM_MAX THEN num = NUM_MAX - (num - NUM_MAX) WHILE rs[num, HASH_EXISTS] num = num + j WEND ENDIF RESULT = num FEND FUNCTION GetNextNumCheat(num, var a[], var rs[], i) RESULT = num + INT(POWER(2, 7 - rs[num])) + 1 FEND
こっちのスクリプトを起動すると、同じディレクトリーにあるStars.uwsを起動して、勝手にときだします。
GetNextNumが番号を推測する関数ですが、元のスクリプトのロジックは入っていません。
学習もしないため、正答率は75%程度です。
☆の数の最大数がわかるなら、もう少しマシにできるかな。
もちろん、元のスクリプトのロジックを組み込んだGetNextNumCheatにすると、正答率は100%です。
今回の目的
「完成された人工知能はもはや人工知能ではない。それは、、、システム」
それは誰の言葉だったか忘れましたが、そこを目指したものです。
ようは、エキスパートシステム(モデルは私ですが)。
ちゃんと学習型人工知能を作成すれば、すぐに100%になると思いますが、
それを書くのは面倒だったもので。