コンピュータ将棋①
大富豪
大富豪を作りたくて書き始まったプログラム。
プレイヤーの数を4人で想定してシャッフルしていますが、可変にすると難しいことになりそうです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Card001
{
class Program
{
static List<Card> card = new List<Card>();
static void Main(string[] args)
{
InitCardType();
var x = GetUniqRandomNumbersEasy(0, 53, 53);
int[,] a = new int[2, 53];
int i = 0;
foreach(var s in x)
{
a[1, i] = s;
if(0 == (i % 4))
{
a[0, i] = 0;
}
if (1 == (i % 4))
{
a[0, i] = 1;
}
if (2 == (i % 4))
{
a[0, i] = 2;
}
if (3 == (i % 4))
{
a[0, i] = 3;
}
string str = string.Format("{0}-{1}", a[0, i], a[1, i]);
Console.WriteLine(str);
i++;
}
for(int j=0;j<53;j++)
{
if(a[0, j] == 0)
{
Console.WriteLine(card[a[1, j]].cardName);
}
}
}
static int GetCardNum(IEnumerable<int> x, int num)
{
int rtn = -1;
foreach (var s in x)
{
if (s == num)
return s;
}
return rtn;
}
static IEnumerable<int> GetUniqRandomNumbersEasy(int rangeBegin, int rangeEnd, int count)
{
// 指定された範囲の整数で埋めたリストを用意する
List<int> work
= Enumerable.Range(rangeBegin, rangeEnd - rangeBegin + 1).ToList();
// workからランダムに取り出して、順に返していく(count回繰り返す)
var rnd = new Random();
for (int i = 0; i < count; i++)
{
// workからランダムに1つ選んで値を取り出す
int pos = rnd.Next(0, work.Count);
int value = work[pos];
work.RemoveAt(pos); // 取り出した値はリストから取り去る
// 取り出した値を順に返す
yield return value;
}
}
static void InitCardType()
{
card.Add(new Card(0, "Jocker"));
card.Add(new Card(1, "クラブ-エース(1)"));
card.Add(new Card(2, "クラブ-デュース(2)"));
card.Add(new Card(3, "クラブ-トレイ(3)"));
card.Add(new Card(4, "クラブ-ケイト(4)"));
card.Add(new Card(5, "クラブ-シンク(5)"));
card.Add(new Card(6, "クラブ-サイス(6)"));
card.Add(new Card(7, "クラブ-セブン(7)"));
card.Add(new Card(8, "クラブ-エイト(8)"));
card.Add(new Card(9, "クラブ-ナイン(9)"));
card.Add(new Card(10, "クラブ-テン(10)"));
card.Add(new Card(11, "クラブ-ジャック(11)"));
card.Add(new Card(12, "クラブ-クイーン(12)"));
card.Add(new Card(13, "クラブ-キング(13)"));
card.Add(new Card(14, "ダイア-エース(1)"));
card.Add(new Card(15, "ダイア-デュース(2)"));
card.Add(new Card(16, "ダイア-トレイ(3)"));
card.Add(new Card(17, "ダイア-ケイト(4)"));
card.Add(new Card(18, "ダイア-シンク(5)"));
card.Add(new Card(19, "ダイア-サイス(6)"));
card.Add(new Card(20, "ダイア-セブン(7)"));
card.Add(new Card(21, "ダイア-エイト(8)"));
card.Add(new Card(22, "ダイア-ナイン(9)"));
card.Add(new Card(23, "ダイア-テン(10)"));
card.Add(new Card(24, "ダイア-ジャック(11)"));
card.Add(new Card(25, "ダイア-クイーン(12)"));
card.Add(new Card(26, "ダイア-キング(13)"));
card.Add(new Card(27, "ハート-エース(1)"));
card.Add(new Card(28, "ハート-デュース(2)"));
card.Add(new Card(29, "ハート-トレイ(3)"));
card.Add(new Card(30, "ハート-ケイト(4)"));
card.Add(new Card(31, "ハート-シンク(5)"));
card.Add(new Card(32, "ハート-サイス(6)"));
card.Add(new Card(33, "ハート-セブン(7)"));
card.Add(new Card(34, "ハート-エイト(8)"));
card.Add(new Card(35, "ハート-ナイン(9)"));
card.Add(new Card(36, "ハート-テン(10)"));
card.Add(new Card(37, "ハート-ジャック(11)"));
card.Add(new Card(38, "ハート-クイーン(12)"));
card.Add(new Card(39, "ハート-キング(13)"));
card.Add(new Card(40, "スペード-エース(1)"));
card.Add(new Card(41, "スペード-デュース(2)"));
card.Add(new Card(42, "スペード-トレイ(3)"));
card.Add(new Card(43, "スペード-ケイト(4)"));
card.Add(new Card(44, "スペード-シンク(5)"));
card.Add(new Card(45, "スペード-サイス(6)"));
card.Add(new Card(46, "スペード-セブン(7)"));
card.Add(new Card(47, "スペード-エイト(8)"));
card.Add(new Card(48, "スペード-ナイン(9)"));
card.Add(new Card(49, "スペード-テン(10)"));
card.Add(new Card(50, "スペード-ジャック(11)"));
card.Add(new Card(51, "スペード-クイーン(12)"));
card.Add(new Card(52, "スペード-キング(13)"));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Card001
{
class Card
{
public int id;
public string cardName;
public Card(int id, string cardName)
{
this.id = id;
this.cardName = cardName;
}
}
}
コンピュータ将棋を実感してみる①
暑いですね。
久しぶりにバイクで外に出て、スポンジとシャンプーを買ってきたので、洗車しました。
マオマオ、ごめんな。汚れたままで…。
最近凝っている話題の中に、コンピュータ将棋があります。
電王戦で、実際にプロ棋士と対戦しているようなプログラムを作ることはとても大変なことですが、将棋のルール上指すことができる手を探し出すプログラムを書くことができたので、より深く、関係者の皆さんがどんなことを考えながらプログラムを組み立てているのかが気になって、いろいろ調べてみました。
将棋所というプログラムがあるようです。
これは、コンピュータ将棋の対局の場を提供するもので、自作の思考エンジン(将棋の戦略を考えるプログラム)を登録してあげると、プログラム対プログラムの対戦が実現できます。
将棋所の作者の方が作った、思考エンジンと対戦することができるので、動かし方を何回かに分けて解説していきたいと思います。
Mac のキーボード操作
end : command + →
home : command + ←
up :command + ↑
down :command + ↓
PowerShell でプログラムの実行時間を測る
powershell -Command "Measure-Command {.\HachimitsuYogurt.exe}"
{ } のなかに、実行するプログラムのパスを書いてあげると、ミリ秒単位で、
実行時間を測ってくれる便利ものです。
回転変換
win32アプリケーション。
回転変換を行うコードを書いてみた。
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: HDC を使用する描画コードをここに追加してください...
int origin = 1000;
//背景色を設定する
SelectObject(hdc, GetStockObject(GRAY_BRUSH));
Rectangle(hdc, 0, 0, 1980, 1200);
//グリッドを引いて、見やすくする
for (int i = 0; i < origin; i++)
{
SetPixel(hdc, i, origin, 0xffff00);
SetPixel(hdc, origin, i, 0xffff00);
}
//変数の宣言
double a1, a2, b1, b2;
double degree = 60;
double rad = degree * PI / 180.0;
double x, y;
//初期値を、(600, 400)に設定
x = 600.0;
y = 400.0;
MoveToEx(hdc, x + origin, -y + origin, NULL);
LineTo(hdc, origin, origin);
//変換前の座標から、原点に向かって線を引く
//MoveToEx(hdc, x + 800, y + 800, NULL);
//LineTo(hdc, 800, 800);
//一次変換
a1 = cos(rad) * x;
a2 = sin(rad) * x;
b1 = -sin(rad) * y;
b2 = cos(rad) * y;
x = a1 + b1;
y = a2 + b2;
//変換後の座標から、原点に向かって線を引く
SetPixel(hdc, x+ origin, -y+ origin, 0xFF0000);
MoveToEx(hdc, x+ origin, -y+ origin, NULL);
LineTo(hdc, origin, origin);
EndPaint(hWnd, &ps);
}
break;