今回作るのは、イメージを読み込んで利用するパズルゲームです。イメージファイルを読み込むとそれを 9 分割し、ランダムに混ぜます。
プレビューのイメージをフォーム上クリックして配置、すべて正しい場所に配置できればクリアです。

フォーム作成
サイズ:500 x 400
背景色:適当

PictureBox配置
- (Name) : PlayBox
- Size : 300 x 300
- BackColor : white
プレビュー用PictureBox配置
- (Name) : Preview
- Size : 100 x 100
- BackColor : white

メニュー作成
MenuStrip をフォームにドロップ、下記のようにメニュー追加

ダイアログ作成
openFileDialog をフォームにドロップ、フィルターを設定
- Image Files (*.png, *.jpg) | *.png; *.jpg

イベント設定
PlayBox
- MouseDown : PlayBox_MouseDown
- Paint : PlayBox_Paint
Preview
LoadImage

ソースコード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PuzzleApp
{
public partial class Form1 : Form
{
// ゲームで使う変数(フィールド)
Image img = null;
bool[] flg = new bool[9];
int[] data = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
int[] answer = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
int current = 0;
bool playflg = false;
bool clearflg = false;
public Form1()
{
InitializeComponent();
}
// 変数関係の初期化処理
private void initialData()
{
flg = new bool[9];
data = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
answer = new int[] { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
Random r = new Random(Environment.TickCount);
for (int i = 0; i < 100; i++)
{
int a = r.Next(9);
int b = r.Next(9);
int n = data[a];
data[a] = data[b];
data[b] = n;
}
current = 0;
playflg = true;
clearflg = false;
}
// クリアしたかどうかをチェック
private void checkClear()
{
bool flg = true;
for (int i = 0; i < 9; i++)
{
if (answer[i] != i) { flg = false; }
}
clearflg = flg;
}
// ゲームが終わったかどうかチェック
private void checkGameEnd()
{
bool flg = false;
for (int i = 0; i < 9; i++)
{
if (answer[i] == -1) { flg = true; }
}
playflg = flg;
if (playflg == false)
{
this.checkClear();
}
}
// オープンダイアログを開いてイメージファイルをロードする
private void LoadImage_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog(this) == DialogResult.OK)
{
img = Image.FromFile(openFileDialog1.FileName);
this.initialData();
this.Refresh();
}
}
// PlayBoxの表示
private void PlayBox_Paint(object sender, PaintEventArgs e)
{
if (img == null) { return; }
Graphics g = e.Graphics;
for (int i = 0; i < 9; i++)
{
if (flg[i] == false) { continue; }
if (answer[i] == -1) { continue; }
int x1 = i % 3;
int y1 = i / 3;
int x2 = answer[i] % 3;
int y2 = answer[i] / 3;
Rectangle r1 = new Rectangle(100 * x1, 100 * y1, 100, 100);
Rectangle r2 = new Rectangle(100 * x2, 100 * y2, 100, 100);
g.DrawImage(img, r1, r2, GraphicsUnit.Pixel);
}
if (playflg == false)
{
if (clearflg)
{
g.DrawString("CLEAR!!",
new Font("Impact", 48, FontStyle.Bold),
new SolidBrush(Color.Red),
new Point(40, 100));
}
else
{
g.DrawString("GAMEOVER...",
new Font("Impact", 36, FontStyle.Bold),
new SolidBrush(Color.Blue),
new Point(20, 200));
}
}
}
// PlayBoxをクリックした時の処理
private void PlayBox_MouseDown(object sender, MouseEventArgs e)
{
if (playflg == false) { return; }
if (img == null) { return; }
if (current > 8) { return; }
int x = e.X / 100;
int y = e.Y / 100;
if (x < 0) { return; }
if (y < 0) { return; }
if (x >= 3) { return; }
if (y >= 3) { return; }
int n = x + y * 3;
flg[n] = true;
answer[n] = data[current];
current++;
this.checkGameEnd();
this.Refresh();
}
// previewの表示
private void Preview_Paint(object sender, PaintEventArgs e)
{
if (img == null) { return; }
if (current > 8) { return; }
int x = data[current] % 3;
int y = data[current] / 3;
Graphics g = e.Graphics;
Rectangle r1 = new Rectangle(0, 0, 100, 100);
Rectangle r2 = new Rectangle(x * 100, y * 100, 100, 100);
g.DrawImage(img, r1, r2, GraphicsUnit.Pixel);
}
}
}
実行結果


参考
http://www18.big.or.jp/~neon2/bunkatu/tips9.shtml