AutoHotKeyでマインスイーパを自動で解く
マインスイーパを自動で解くっていっても、裏技使ってるからなんともいえない。
しかも、ニコ動でTASさんが解いたほうが断トツで速いと。。。
でも、このAutoHotKeyってソフトWindowsの作業をほとんど自動化してくれるので便利。
日本語対応で文字形式はUTF-8だから注意してね。
あと、色付けはBasicにしてみた。あと、XPで動いてる。
; utf-8 mode := "" mineHeight := 0 mineWidth := 0 Gui, Add, Radio, vB Checked1, 初級 Gui, Add, Radio, vI, 中級 Gui, Add, Radio, vE, 上級 Gui, Add, Button, , 決定 Gui, Show Loop { Sleep, 100 } Button決定: GUI, Submit If B = 1 { mode := "初級" mineHeight := 9 mineWidth := 9 } If I = 1 { mode := "中級" mineHeight := 16 mineWidth := 16 } If E = 1 { mode := "上級" mineHeight := 16 mineWidth := 30 } IfWinNotExist マインスイーパ { MsgBox, 4, , マインスイーパを起動しますか? IfMsgBox, Yes { Run, C:\WINDOWS\system32\winmine.exe } else { ExitApp } } WinActivate, マインスイーパ Send, xyzzy+{Enter} CoordMode, Pixel, Screen WinMenuSelectItem, マインスイーパ, , ゲーム, % mode y := 104 Loop, % mineHeight { x := 24 Loop, % mineWidth { MouseMove, % x, % y, 0 PixelGetColor, color, 0, 0 If % color = 0xFFFFFF { MouseClick, Left, % x, % y, 1, 0 } x += 16 } y += 16 } MsgBox, congratulations! WinClose, マインスイーパ Gui, Destroy GuiClose: ExitApp
AutoHotKeyを使って遊ぶ
前にマインスイーパの裏ワザを使用して、
AutoHotKeyで解くプログラム、また作り直してって貼っておこう。
他にもやりたいことあるし、いろいろできるソフトだから。
CygwinにODEをインストール
※最初に注意として、既にCygwin版ODEがありますので、そちらをインストールしたほうが早いです。
まず、
$ cygcheck -c cygwin gcc4-g++ opengl Cygwin Package Information Package Version Status cygwin 1.7.9-1 OK gcc4-g++ 4.5.3-2 OK opengl 1.1.0-10 OK
という環境の32bit XPマシンを使用しています。
ode-0.11.1をインストールしていきます。
ODEをダウンロードして適当なディレクトリに解凍して移動します。
cd ~/src/ode-0.11.1
sh ./autogen.sh
ここで、./configureを編集します。
テキストエディタを使用し、DEFS=を検索します。
すると
DEFS=-DHAVE_CONFIG_H
が見つかると思います。
これを
DEFS="-DHAVE_CONFIG_H -D_WIN32 -DUSE_OPENGL32"
に書き換えて保存します。
あとは
./configure
make
make install
という手順でインストールできます。
/ode-0.11.1ode/demoの中にデモがあり、しばらく遊べます。
Arduinoを使って1602LCDで高速素数表示をした
素数を数えると精神衛生上によいと聞いたので、
LCDキャラクタディスプレイに素数を表示して冷静になろうと思う。
リンク先にあるミラーラビン素数判定法というものを、そのまま実装した。
結果が合っているかの確認はしていないけど、落ち着く可能性はあると思う。
IDEのバージョンは0022で
ボードは"Arduino Pro or Pro Mini (3.3V,8MHz)w/ATmega168"を使用した。
以下ソース
// 高速素数表示、時間付 #include <stdint.h> #include <stdio.h> #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2); void setup() { randomSeed(analogRead(0)); lcd.begin(16, 2); lcd.clear(); lcd.setCursor(0, 0); } uintmax_t num = 100000UL; // 最初に判定したい数 uint32_t time; char str[20]; void loop() { if (isPrime(num)) { time = millis(); snprintf(str, sizeof(str), "PrimeNum:%7lu", num); lcd.setCursor(0, 0); lcd.print(str); snprintf(str, sizeof(str), " %02luh%02lum%02lus%03lums", time / 1000UL / 3600UL % 24UL, time / 1000UL / 60UL % 60UL, time / 1000UL % 60UL, time % 1000UL); lcd.setCursor(0, 1); lcd.print(str); } num++; } // ミラー・ラビン素数判定法 wikipediaから引用・改変 bool isPrime(const uintmax_t n) { if (n == 2) { return true; } if (n == 1 || (n & 1) == 0) { return false; } uintmax_t d = n - 1; while ((d & 1) == 0) { d >>= 1; } uintmax_t a, t, y; for (int i = 0; i < 20; i++) { a = random(1, n-1); t = d; y = pow(a, t, n); while (t != n-1 && y != 1 && y != n-1) { y = (y * y) % n; t <<= 1; } if (y != n-1 && (t & 1) == 0) { return false; } } return true; } uintmax_t pow(uintmax_t base, uintmax_t power, const uintmax_t mod) { uintmax_t result = 1; while (power > 0) { if ((power & 1) == 1) { result = (result * base) % mod; } base = (base * base) % mod; power >>= 1; } return result; }
写真か動画取ればよかった。
四次元配列の一次元化
#include <stdio.h> #define O 2 #define P 3 #define Q 4 #define R 5 int main() { int i, j, k, l; int nums4[O][P][Q][R]; int nums1[O*P*Q*R]; for (i = 0; i < O; i++) { for (j = 0; j < P; j++) { for (k = 0; k < Q; k++) { for (l = 0; l < R; l++) { nums4[i][j][k][l] = i*P*Q*R + j*Q*R + k*R + l; printf("i:%d j:%d k:%d l:%d nums4:%d\n", i, j, k, l, nums4[i][j][k][l]); } } } } puts(""); for (i = 0; i < O; i++) { for (j = 0; j < P; j++) { for (k = 0; k < Q; k++) { for (l = 0; l < R; l++) { nums1[i*P*Q*R + j*Q*R + k*R + l] = nums4[i][j][k][l]; printf("i:%d j:%d k:%d l:%d nums1:%d\n", i, j, k, l, nums1[i*P*Q*R + j*Q*R + k*R + l]); } } } } puts(""); for (i = 0; i < O*P*Q*R; i++) { printf("i:%d nums1:%d\n", i, nums1[i]); } puts(""); printf("sizeof(nums4):%d sizeof(nums1):%d\n", sizeof(nums4)/sizeof(int), sizeof(nums1)/sizeof(int)); return 0; }
多分、あってる。
ソースコードに全然自信ないし、配列関係は間違いやすいから、扱いには十分注意してね。
世の中には、一次元配列が扱いやすい状況があったりするはず。
ていうか、一次元配列アクセスするときはfor文も一重化すれば見やすくなる。
追記
蛇足だけど、for文一重化してアクセスしたコードを追加した。
cygwinでopenglのコンパイルの仕方
gcc version 4.3.4 20090804 (release) 1 (GCC)で
下記の"GLUTによる「手抜き」OpenGL入門:"様にあるサンプルソースを
ちょっと変えてコンパイルしてみた
#define _WIN32 #define USE_OPENGL32 #include <GL/glut.h> void display(void) { glClear(GL_COLOR_BUFFER_BIT); glFlush(); } void init(void) { glClearColor(0.0, 0.0, 1.0, 1.0); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutDisplayFunc(display); init(); glutMainLoop(); return 0; }
コマンドは
gcc test.c -O3 -lglut32 -lglu32 -lopengl32 ./a
ヘッダファイル見て、#defineしてみたら動いた
これでgmpライブラリと併用出来る