Skip to content

Instantly share code, notes, and snippets.

@cos65535
Last active December 7, 2015 17:31
Show Gist options
  • Save cos65535/e44bfdb0a07ee4e50586 to your computer and use it in GitHub Desktop.
Save cos65535/e44bfdb0a07ee4e50586 to your computer and use it in GitHub Desktop.
SECCON 2015オンライン予選 QR puzzle (Windows)
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