Last active
December 7, 2015 17:31
-
-
Save cos65535/e44bfdb0a07ee4e50586 to your computer and use it in GitHub Desktop.
SECCON 2015オンライン予選 QR puzzle (Windows)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Data; | |
using System.Drawing; | |
using System.Linq; | |
using System.Text; | |
using System.Windows.Forms; | |
using System.Runtime.InteropServices; | |
using System.Diagnostics; | |
using ZXing; // for DllImport | |
namespace seccon_qr_puzzle | |
{ | |
public partial class Form1 : Form | |
{ | |
string windowTitle = "QRpuzzle for SECCON 2015 (by KeigoYAMAZAKI)"; | |
int leftSide = 18; | |
int topSide = 72; | |
int tileWidth = 160; | |
int tileHeight = 160; | |
int offset = 6; | |
Bitmap[] tiles; | |
Bitmap ansImage; | |
public Form1() | |
{ | |
tiles = new Bitmap[100]; | |
InitializeComponent(); | |
foreach (Process p in Process.GetProcesses()) | |
{ | |
if (p.MainWindowHandle != IntPtr.Zero) | |
{ | |
Console.WriteLine(p.ProcessName + " : " + p.MainWindowTitle); | |
} | |
} | |
} | |
private void button1_Click(object sender, EventArgs e) | |
{ | |
for (int iter = 0; iter < 300; iter++) | |
{ | |
GetGame(); | |
SortTiles(); | |
ansImage = MergeBitmap(); | |
BarcodeReader reader = new BarcodeReader(); | |
Result result = null; | |
for (int i = 0; i < 2; i++) | |
{ | |
for (int j = 0; j < 2; j++) | |
{ | |
for (int k = 0; k < 4; k++) | |
{ | |
result = reader.Decode(ansImage); | |
if (result != null) { goto OK; } | |
ansImage.RotateFlip(RotateFlipType.Rotate90FlipNone); | |
} | |
ansImage.RotateFlip(RotateFlipType.RotateNoneFlipX); | |
} | |
ansImage.RotateFlip(RotateFlipType.RotateNoneFlipY); | |
} | |
OK: | |
pictureBox1.Image = ansImage; | |
if (result != null) | |
{ | |
string ans = result.Text; | |
System.Console.WriteLine(ans); | |
SendAns(ans); | |
} | |
else | |
{ | |
System.Windows.Forms.MessageBox.Show("読み取りに失敗しました"); | |
} | |
} | |
} | |
public void GetGame() | |
{ | |
ActiveWindow(windowTitle); | |
MoveWindow(windowTitle, 0, 0); | |
//Bitmapの作成 | |
Bitmap bmp = new Bitmap(550, 650); | |
//Graphicsの作成 | |
Graphics g = Graphics.FromImage(bmp); | |
//画面全体をコピーする | |
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), bmp.Size); | |
//解放 | |
g.Dispose(); | |
for (int y = 0; y < 3; y++) { | |
for (int x = 0; x < 3; x++) { | |
tiles[y * 3 + x] = bmp.Clone(new Rectangle(leftSide + x * (tileWidth + offset), topSide + y * (tileHeight + offset), tileWidth, tileHeight), System.Drawing.Imaging.PixelFormat.Format24bppRgb); | |
} | |
} | |
} | |
public void SortTiles() | |
{ | |
for (int i = 0; i < 9; i++) | |
{ | |
for (int j = 0; j < 9; j++) | |
{ | |
if (GetTilePos(tiles[j]) == i) | |
{ | |
Bitmap temp = tiles[i]; | |
tiles[i] = tiles[j]; | |
tiles[j] = temp; | |
break; | |
} | |
} | |
} | |
} | |
public int GetTilePos(Bitmap tile) | |
{ | |
int[] sums = new int[9]; | |
for (int i = 0; i < 3; i++) | |
{ | |
int sy = tileHeight / 3 * i; | |
for (int j = 0; j < 3; j++) | |
{ | |
int sx = tileWidth / 3 * j; | |
for (int y = 0; y < tileHeight / 3; y++) | |
{ | |
for (int x = 0; x < tileWidth / 3; x++) | |
{ | |
Color c = tile.GetPixel(sx + x, sy + y); | |
sums[i * 3 + j] += c.R < 200 ? 1 : 0; | |
} | |
} | |
} | |
} | |
int ypos = 1; | |
int xpos = 1; | |
if (sums[0] == 0 && sums[2] == 0) { ypos = 0; } | |
if (sums[6] == 0 && sums[8] == 0) { ypos = 2; } | |
if (sums[0] == 0 && sums[6] == 0) { xpos = 0; } | |
if (sums[2] == 0 && sums[8] == 0) { xpos = 2; } | |
return ypos * 3 + xpos; | |
} | |
public Bitmap MergeBitmap() { | |
Bitmap ret = new Bitmap(tileWidth * 3, tileHeight * 3); | |
for (int i = 0; i < 3; i++) | |
{ | |
int sy = tileHeight * i; | |
for (int j = 0; j < 3; j++) | |
{ | |
int sx = tileWidth * j; | |
for (int y = 0; y < tileHeight; y++) | |
{ | |
for (int x = 0; x < tileWidth; x++) | |
{ | |
Color c = tiles[i * 3 + j].GetPixel(x, y); | |
ret.SetPixel(sx + x, sy + y, c); | |
} | |
} | |
} | |
} | |
return ret; | |
} | |
public void SendAns(string ans) | |
{ | |
ActiveWindow(windowTitle); | |
System.Threading.Thread.Sleep(1000); | |
SendKeys.SendWait(ans); | |
System.Threading.Thread.Sleep(1000); | |
} | |
[DllImport("user32.dll")] | |
extern static IntPtr FindWindow(string lpClassName, string lpWindowName); | |
[DllImport("user32.dll")] | |
extern static bool IsWindowVisible(IntPtr hWnd); | |
[DllImport("user32.dll")] | |
extern static bool SetForegroundWindow(IntPtr hWnd); | |
static public void ActiveWindow(string windowTitle) | |
{ | |
IntPtr hWnd = FindWindow(null, windowTitle); | |
if (hWnd != IntPtr.Zero && IsWindowVisible(hWnd)) | |
{ | |
SetForegroundWindow(hWnd); | |
} | |
} | |
//MoveWindow関数の宣言 | |
[System.Runtime.InteropServices.DllImport("user32.dll")] | |
private static extern int MoveWindow(IntPtr hwnd, int x, int y, | |
int nWidth, int nHeight, int bRepaint); | |
static public void MoveWindow(string windowTitle, int x, int y) | |
{ | |
IntPtr hWnd = FindWindow(null, windowTitle); | |
if (hWnd != IntPtr.Zero && IsWindowVisible(hWnd)) | |
{ | |
MoveWindow(hWnd, x, y, 550, 650, 1); | |
} | |
System.Threading.Thread.Sleep(300); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment