<html>
<meta charset="utf-8">
<head>
<hta:application
id="SimpleML"
applicationname="SimpleML"
version="1.0.0.0"
border="thick"
borderstyle="normal"
innerborder="no"
selection="no"
scroll="no"
contextmenu="no"
windowstate="normal" />
<!-- 실행 개체 -->
<script language="javascript">
// Initialization
window.onload = function () {
// Document Titling
document.title = Locale.getTitle();
// Document Styling
document.body.bgColor = "#b0b0b0";
document.body.style.padding = "0 0 0 0";
document.body.style.margin = "0 0 0 0";
//
var panel = document.createElement("DIV");
panel.style.width = "100%";
panel.style.height = "100%";
document.body.appendChild(panel);
//
var myGame = GridGame.create(18, 18, 5);
panel.appendChild(myGame);
//
myGame.players[0] = GridPlayer.createUser();
myGame.players[1] = GridPlayer.createAI();
//myGame.players[2] = GridPlayer.createCPU(); /* third player(for test purpose) */
//myGame.players[2].color = "blue";
//myGame.alert();
myGame.start();
}
</script>
<!-- 소스 코드 -->
<script language="javascript">
Locale = {};
Locale.getTitle = function () { return "인공지능 테스트 샘플"; };
</script>
<script language="javascript">
GridGame = {};
GridGame.create = function (m, n, k) {
var game = document.createElement("DIV");
game.m = m;
game.n = n;
game.k = k;
game.victoryPlayer = -1;
game.currentPlayer = -1;
game.players = [];
game.logs = [];
game.clickable = false;
game.playerMarkable = false;
game.cells = [];
game._createCells = function () {
for (var y = 0; y < game.n; y++) {
game.cells[y] = [];
for (var x = 0; x < game.m; x++) {
var cell = GameCell.create(game, x, y, m, n);
game.cells[y][x] = cell;
game.appendChild(cell);
}
}
}
game.alert = function () {
var alertMsg = "M:" + game.m + ", N:" + game.n + ", K:" + game.k + "\n";
alertMsg += "Players\n";
for (var i = 0; i < game.players.length; i++)
alertMsg += "[" + i + "] " + game.players[i].name + "\n";
alert(alertMsg);
}
game.gridState = function (p) {
var state = "";
for (var y = 0; y < game.n; y++) {
for (var x = 0; x < game.m; x++) {
var owner = game.cells[y][x].owner;
if (owner < 0) {
state += "0";
continue;
}
if (owner == p)
state += "A";
else
state += "B";
}
}
return state;
}
game._count1D = function (x, y, dx, dy, p) {
var cx = x;
var cy = y;
var c = 0;
while (true) {
cx += dx;
cy += dy;
if (cx < 0)
return c;
if (cy < 0)
return c;
if (cx >= game.m)
return c;
if (cy >= game.n)
return c;
if (p != game.cells[cy][cx].owner)
return c;
c++;
}
}
game._count2D = function (x, y, dx, dy, p) {
var d1 = game._count1D(x, y, dx, dy, p);
var d2 = game._count1D(x, y, -dx, -dy, p);
return 1 + d1 + d2;
}
game._check8DK = function (x, y, dk) {
var cellOwner = game.cells[y][x].owner;
if (game._count2D(x, y, 1, 0, cellOwner) >= dk)
return cellOwner;
if (game._count2D(x, y, 0, 1, cellOwner) >= dk)
return cellOwner;
if (game._count2D(x, y, 1, 1, cellOwner) >= dk)
return cellOwner;
if (game._count2D(x, y, -1, 1, cellOwner) >= dk)
return cellOwner;
return -1;
}
game._checkWinOrLose = function () {
// 승패 초기화
game.victoryPlayer = -1;
// 셀을 오가면서 마킹 체크
var hasAnEmptyCell = false;
for (var y = 0; y < game.n; y++) {
for (var x = 0; x < game.m; x++) {
if (game.cells[y][x].owner < 0) {
hasAnEmptyCell = true;
continue;
}
var lastCheckedPlayer = game._check8DK(x, y, game.k);
if (lastCheckedPlayer < 0)
continue;
game.victoryPlayer = lastCheckedPlayer;
return true;
}
}
// 판이 꽉 찼다면 무승부
if (!hasAnEmptyCell) {
return true;
}
// false = 승패 판가름이 안 남
return false;
}
game._turnStart = function () {
var p = game.players[game.currentPlayer];
game.playerMarkable = true;
p.onturn(game);
}
game._turnNext = function () {
game.currentPlayer = game.currentPlayer + 1;
if (game.currentPlayer >= game.players.length)
game.currentPlayer = 0;
game._turnStart();
}
game.tryMark = function (x, y) {
if (game.cells[y][x].owner >= 0)
return false;
if (!game.playerMarkable)
return false;
return true;
}
game.gridMark = function (x, y) {
//alert(x + ", " + y);
// 마킹 가능 조건 확인
if (!game.tryMark(x, y))
return false;
// 마킹 전 로그
var log = game.logs[game.currentPlayer];
var logPos = log.length;
log[logPos] = {};
log[logPos].state = game.gridState(game.currentPlayer);
log[logPos].x = x;
log[logPos].y = y;
// 마킹
game.clickable = false;
game.playerMarkable = false;
game.cells[y][x].owner = game.currentPlayer;
game.cells[y][x].style.backgroundColor = game.players[game.cells[y][x].owner].color;
// 승패여부 체크
if (game._checkWinOrLose()) {
alert("승패 결과 = " + game.victoryPlayer);
// 각 플레이어에게 승패 결과 피드백
for (var p = 0; p < game.players.length; p++)
game.players[p].onfeedback(game);
// 로그 출력
//var s = "";
//for (var i = 0; i < game.logs[0].length; i++)
// s += game.logs[0][i].state + ", X:" + game.logs[0][i].x + ", Y:" + game.logs[0][i].y + "\n";
//alert(s);
// 턴 안넘기고 게임 오버
return true;
}
// 턴 넘김
game._turnNext();
return true;
}
game.start = function () {
// 판 유효성 검사
if (game.cells.length < 1)
throw "판 없음";
// 플레이어 유효성 검사
if (game.players.length < 1)
throw "플레이어 없음";
// 게임 초기화
game.logs = new Array();
game.currentPlayer = 0;
for (var p = 0; p < game.players.length; p++) {
game.logs[p] = new Array();
game.players[p].index = p;
game.players[p].oninit(game);
}
// 턴 개시
game._turnStart();
}
game._createCells();
return game;
}
GameCell = {};
GameCell.create = function (game, x, y, m, n) {
var w = 100 / m;
var h = 100 / n;
var tmpCell = document.createElement("DIV");
tmpCell.style.position = "absolute";
tmpCell.style.backgroundColor = "white";
tmpCell.style.width = w + "%";
tmpCell.style.height = h + "%";
tmpCell.style.left = x * w + "%";
tmpCell.style.top = y * h + "%";
tmpCell.style.border = "2px solid black";
tmpCell.style.textAlign = "center";
tmpCell.owner = -1;
tmpCell.onclick = function () {
if (!game.clickable) {
alert("어허...");
return;
}
game.gridMark(x, y);
}
return tmpCell;
}
</script>
<script language="javascript">
GridPlayer = {};
GridPlayer.createUser = function () {
var player = {};
player.name = "유저";
player.color = "green";
player.index = -1;
player.onturn = function (game) {
//alert("유저 차례");
// 플레이어가 마우스로 선택할 수 있도록 활성화
game.clickable = true;
}
player.oninit = function (game) { };
player.onfeedback = function (game) { };
return player;
}
GridPlayer.createCPU = function () {
var player = {};
player.name = "CPU";
player.color = "red";
player.index = -1;
player.onturn = function (game) {
//alert("CPU 차례");
for (var y = 0; y < game.n; y++) {
for (var x = 0; x < game.m; x++) {
if (!game.tryMark(x, y))
continue;
game.gridMark(x, y);
return;
}
}
};
player.oninit = function (game) { };
player.onfeedback = function (game) { };
return player;
}
GridPlayer.createAI = function () {
var player = {};
player.name = "AI";
player.color = "blue";
player.index = -1;
player.brain = {};
// TODO : AI 턴 구현하기
player.onturn = function (game) {
//alert("CPU 차례");
var state = game.gridState(player.index);
// 상황에 대한 지식이 없다면, 랜덤 배치를 시도
if ("undefined" === typeof (player.brain[state])) {
player.brain[state] = {};
}
// 지식이 있다면, 불러와 최적의 수를 두려고 시도
else {
var knowlegde = player.brain[state];
// 최적의 수를 반환받으려 시도
for (var key in knowlegde) {
if (!knowlegde.hasOwnProperty(key))
continue;
}
}
for (var y = 0; y < game.n; y++) {
for (var x = 0; x < game.m; x++) {
if (!game.tryMark(x, y))
continue;
game.gridMark(x, y);
return;
}
}
};
// TODO : AI 초기화 구현하기
player.oninit = function (game) { };
// TODO : AI 피드백 구현하기
player.onfeedback = function (game) { };
return player;
}
</script>
<script language="javascript">
LogManager = {};
LogManager.create = function () {
var tmpLogmgr = {};
tmpLogmgr.size = 0;
tmpLogmgr.m = [];
tmpLogmgr.p = [];
tmpLogmgr.clear = function () { tmpLogmgr.size = 0; }
tmpLogmgr.log = function (pattern, index) {
tmpLogmgr.m[tmpLogmgr.size] = index;
tmpLogmgr.p[tmpLogmgr.size] = pattern;
tmpLogmgr.size++;
}
tmpLogmgr.get = function (index) {
return tmpLogmgr.m[index];
}
tmpLogmgr.getPattern = function (index) {
return tmpLogmgr.p[index];
}
tmpLogmgr.write = function (fname) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var path = unescape(document.location);
path = path.substring(8, path.lastIndexOf("/") + 1);
var s = fso.OpentextFile(path + fname, 2, true);
for (var i = 0; i < tmpLogmgr.size; i++) {
s.Write(tmpLogmgr.p[i]);
s.WriteLine(" " + tmpLogmgr.m[i]);
}
s.Close();
fso = null;
}
return tmpLogmgr;
}
</script>
<script language="javascript">
Brain = {};
Brain.create = function (linksize) {
var tmpBrain = {};
tmpBrain.maxneu = linksize;
tmpBrain.memory = {};
tmpBrain.write = function (fname) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var path = unescape(document.location);
path = path.substring(8, path.lastIndexOf("/") + 1);
var s = fso.OpentextFile(path + fname, 2, true);
for (var propertyName in tmpBrain.memory) {
s.Write(propertyName);
for (var i = 0; i < tmpBrain.maxneu; i++)
s.Write(" " + tmpBrain.memory[propertyName].w[i])
s.WriteLine("");
}
s.Close();
fso = null;
}
tmpBrain.have = function (pattern) { return tmpBrain.memory.hasOwnProperty(pattern); }
tmpBrain.get = function (pattern, selectionIndex) {
if (!tmpBrain.memory.hasOwnProperty(pattern))
return 0;
return tmpBrain.memory[pattern].w[selectionIndex];
}
tmpBrain.remember = function (pattern, selectionIndex, weight) {
if (!tmpBrain.memory.hasOwnProperty(pattern)) {
tmpBrain.memory[pattern] = {};
tmpBrain.memory[pattern].w = [];
for (var i = 0; i < tmpBrain.maxneu; i++)
tmpBrain.memory[pattern].w[i] = 0;
}
tmpBrain.memory[pattern].w[selectionIndex] = weight;
}
tmpBrain.read = function (fname) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var path = unescape(document.location);
path = path.substring(8, path.lastIndexOf("/") + 1);
if (!fso.FileExists(path + fname)) {
fso = null;
return
}
var s = fso.OpentextFile(path + fname, 1, true);
//
var line = "";
while (!s.AtEndOfStream) {
line = s.ReadLine();
var arr = line.split(" ");
for (var i = 0; i < tmpBrain.maxneu; i++)
tmpBrain.remember(arr[0], i, Number(arr[i + 1]));
}
//
s.Close();
fso = null;
}
return tmpBrain;
}
</script>
</head>
<body>
</body>
</html>