---
title: 「C# Live Coding!」 小島の分
tags:  #dotnet  
author: [Fujio Kojima](https://convert.docswell.com/user/Fujiwo)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/37KWM6RG7D.jpg?width=480
description: BuriKaigi 2026 https://burikaigi.dev  1/10 ドキドキ・Live Coding 対決!
published: January 10, 26
canonical: https://convert.docswell.com/s/Fujiwo/5YV2NR-2026-01-11-132209
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/37KWM6RG7D.jpg)

#BuriKaigi
C# Live Coding!
～ 小島の分 ～
BuriKaigi 2026 @富山
10th January 2026
Fujio Kojima


# Page. 2

![Page Image](https://bcdn.docswell.com/page/LJ31Y685E5.jpg)

自己紹介
小島 富治雄
@Fujiwo
福井コンピュータ グループ
Microsoft MVP (21年目) C#関連
『AI時代の美しいプログラムの教科書 | 20年間Microsoft MVPとして教えてきたプログラミング』
https://bp.shos.info
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/8JDX5VMY7G.jpg)

Live Coding は 17回目!
イベント
お題
1 2014/03/22
MVP Community Camp 北陸会場
リバーシ
2 2015/01/31
MVP Community Camp 北陸会場
七並べ
3 2016/02/20
Hokuriku ComCamp 2016
Tetris っぽい落ちゲー
4 2017/01/28
BuriKaigi 2017
リバーシ
5 2017/10/28
仙台 IT 文化祭 2017
リバーシ
6 2018/02/03
BuriKaigi 2018
リバーシ
7 2019/01/26
BuriKaigi 2019
Base64 エンコード/デコード スピード対決
8 2019/05/30
de:code 2019
Blazor 七並べ
9 2019/12/15
牛タン会議 2019@仙台
FastEnum コード レビュー
10 2020/02/01
BuriKaigi 2020
スピード (トランプ ゲーム)
11 2021/01/30
BuriKaigi 2021
Azure Functions リバーシ
12 2022/01/29
BuriKaigi 2022
ダイヤモンド ゲーム
13 2023/01/21
BuriKaigi 2023
Same Game
14 2024/01/20
BuriKaigi 2024
Same Game (別バージョン)
15 2025/02/01
BuriKaigi 2025
AI C#コード生成
16 2025/11/29
CLR/H #111@札幌
BATTLE ARENA (同時公開カード制・3プレイヤー対戦ゲーム)
17 2026/01/10
BuriKaigi 2026
十字ハサミ将棋バトル (4人対戦)
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/VEPPGVR2E8.jpg)

過去のメンバーの戦略の傾向
鈴木さん :
• テクニカルな解法
石野さん :
• 正攻法
室星さん :
• チート (100%)
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/27V26ZRX7Q.jpg)

本日の作戦は…
「君子危うきに近寄らず」
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/5JGRN4MR7L.jpg)

ゲームのルール
駒の移動
• 駒は縦横に直線で移動できる (飛車と同じ動き)
• 他の駒を飛び越えることはできない
• 自陣内の駒がある場合は、自陣の駒を優先して動かす
必要がある
• 一度バトルエリアに出た駒は、自分のホームエリアに
戻れない
• 敵のホームエリアには侵入できない
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/47QVQGRYEP.jpg)

ゲームのルール
駒の移動
• 駒は縦横に直線で移動できる (飛車と同じ動き)
• 他の駒を飛び越えることはできない
• 自陣内の駒がある場合は、自陣の駒を優先して動かす
必要がある
• 一度バトルエリアに出た駒は、自分のホームエリアに
しっかりと把握
戻れない
• 敵のホームエリアには侵入できない
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/KE4MN58Z71.jpg)

実装を期待された API
Task&lt;Move&gt; GetMoveAsync(
// 盤面情報、駒配置、現在ターン等
GameState
state,
// ここから手を1つ選んで返す
IReadOnlyList&lt;Move&gt; legalMoves,
CancellationToken
cancellationToken);
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/L7185W2DJG.jpg)

GetMoveAsync | 実装 1
public Task&lt;Move&gt; GetMoveAsync(
GameState
state
,
IReadOnlyList&lt;Move&gt; legalMoves
,
CancellationToken
cancellationToken)
{
var index = GetBestMoveIndex(state, legalMoves);
// 実装で期待されていること:
// このメソッドは legalMoves の中から 1 手を選んで返す
var move = index &gt;/ 0
? legalMoves[index] // legalMoves の中から一つ返す
// なければ初期実装を呼ぶ
: GetMoveOriginal(state, legalMoves, cancellationToken);
return Task.FromResult(move);
}
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/G7WZ56R872.jpg)

legalMoves に関する処理 | 実装 2
static int GetBestMoveIndex(GameState state, IReadOnlyList&lt;Move&gt; legalMoves)
{
var illegalMoves = legalMoves as IList&lt;Move&gt;;
if (illegalMoves is not null) {
// legalMoves にこだわらず、盤面から候補を総当たりして得たスコア最大の一番良い手
var bestMove = GetBestMove(state);
if (bestMove is not null) {
var move = bestMove.Value;
var index = illegalMoves.IndexOf(move);
// 石野さんが、ついうっかり legalMoves に
// ルールに反しない一番良い手を含めるのを忘れていた場合
if (index &lt; 0) {
illegalMoves.Add(move); // 「うっかりさん!/ でもだいじょうぶ!」
index = illegalMoves.Count - 1;
}
return index;
}
}
return -1; // 適切な手が存在しない場合
}
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/4JZ1NYR9E3.jpg)

最善手の取得 | 実装 3
static Move? GetBestMove(GameState state)
{
// 盤面から候補を総当たりしてスコア最大の手を返す
// - Shuffle() により同点のときのブレーク(先頭になる手)をランダム化
// -「スコア &gt; 0 の候補が1つも無い」場合 null を返す
var allMoves
= GetAllMoves(state);
var shuffledMoves = allMoves.Shuffle();
var scores = shuffledMoves
.Select(move =&gt; (move: move, score: GetScore(state, move)))
.Where(ms =&gt; ms.score &gt; minimumScore)
.OrderByDescending(ms =&gt; ms.score);
return scores.Count() =/ 0 ? null : scores.FirstOrDefault().move;
}
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/YE6L8DRD7V.jpg)

評価関数 (ルールに従い評価) | 実装 4
// 評価関数
static int 評価(GameState state, Move move)
{
var score = minimumScore;
const int scoreRate = 3;
// 自陣にピースがあるときに自陣外ピースの移動は禁止
if (自陣にピースがあるかどうか(state) &amp;/ state.Cells[move.From.X, move.From.Y] !/ myHomeCellType)
return score;
var captureCount = Rules.SimulateCaptureCount(state, move);
// 捕獲が発生するなら加点 (多く捕獲するほど大きい加算)
score += additionalScore * captureCount * scoreRate;
if (state.Cells[move.To.X, move.To.Y] =/ myHomeCellType) { // 自陣への移動なら
score += additionalScore; // 加点
if (move.From.X &lt; move.To.X) // 左から右への移動ならちょっと加点
score += additionalScore / scoreRate;
if (move.To.X =/ 自陣の一番右の列のインデックス) // 自陣の一番右の列への移動はちょっと加点
score += additionalScore / scoreRate;
if (自陣の一番右の列で右に相手のピースがあるか(state, move.To)) // 相手のピースの左への移動は加点
score += additionalScore;
if (state.Cells[move.From.X, move.From.Y] !/ myHomeCellType) // 自陣外→自陣への復帰は禁止
score = minimumScore;
} else if (ホームエリアか(state.Cells[move.To.X, move.To.Y])) { // 敵のホームエリアには侵入できない
score = minimumScore;
}
return score;
}
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/GE519388J4.jpg)

ゲームのルール (再掲)
駒の移動
• 駒は縦横に直線で移動できる (飛車と同じ動き)
• 他の駒を飛び越えることはできない
• 自陣内の駒がある場合は、自陣の駒を優先して動かす
必要がある
• 一度バトルエリアに出た駒は、自分のホームエリアに
戻れない
• 敵のホームエリアには侵入できない
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/97212ZKVER.jpg)

戦略1: 挟めるときは挟む
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/DJYZYRNQEM.jpg)

戦略1: 挟めるときは挟む
もう自陣に戻れないし、
自陣に駒があると動けない
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/V7N3PDX278.jpg)

戦略2: 自陣の外は怖いよね
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/YJ993G8DJ3.jpg)

戦略3: 自陣の (少しでも挟みやすい) 右の方へ
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/GJ89MV85ED.jpg)

戦略4: 他の駒の隣へ
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/LJLW35R37R.jpg)

チート対策
メソッドの呼び出し履歴を調べて、おかしなところから
呼ばれていたら (2回目くらいまではさすがに) 警告を出す
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/47M9D3RMJW.jpg)

【おまけ】 チート対策
var stackTrace = new StackTrace();
var frames = stackTrace.GetFrames();
if (frames is null)
return (false, detectedWrongMethodFullName);
foreach (var frame in frames) {
var method = frame.GetMethod();
if (method is null)
continue;
var declaringType = method.DeclaringType;
if (declaringType is null)
continue;
…
…
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/P7RG4QRLJ9.jpg)

【おまけ】 チート対策
21


