/* 「ピラミッド」 2004/05/19版 THU madpoet@thu.sakura.ne.jp http://thu.sakura.ne.jp/ */ // ピラミッドクラス function Pyramid() { this.id = arguments[0]; var node; if(!(node = document.getElementById(this.id))) { return false; } this.size = 4; // サイズ基本値 this.bgColor = 'limegreen'; // 背景色 var i; for (i = 1; i < arguments.length; i++) { if (i == 1) { this.size = arguments[i]; } else if (i == 2) { this.bgColor = arguments[i]; } } if (this.size < 3) { this.size = 3; } this.ie = false; var agt = navigator.appName; if (agt.match(/Internet Explorer/)){ this.ie = true; } this.cardOpen = false; this.fontSize = Math.floor(this.size * 2.5); this.lineHeight = this.size * 3; this.mode = 'start'; this.card = new TableCard(this.size); this.cardSelect = new Array(); this.cardSelect[0] = new TableCard(this.size, 'orangered', 'lemonchiffon'); this.cardSelect[1] = new TableCard(this.size, 'orangered', 'yellow'); this.point = 0; this.pointCheck = 0; this.cardInit(); this.fieldSet(); this.cardSetInit(); this.buttonSet('start'); } // ピラミッド:カードの初期化 Pyramid.prototype.cardInit = function() { var i; this.oneCardsSet(); this.pyramidCard = new Array(); this.cardState = new Array(); for (i = 0; i < 28; i++) { this.pyramidCard[i] = this.oneCards[0]; this.oneCards = this.oneCards.slice(1); this.cardState[i] = 1; } this.handCard = this.oneCards; this.castCard = new Array(); this.castState = 2; this.check = 0; this.handUse = 0; } // ピラミッド:カードの初期セット Pyramid.prototype.cardSetInit = function() { var i, j, k, l, tmp, id, num, suit, parts; this.cursorClear(); k = 0, l = 0; for (j = 0; j < 7; j++) { for (i = 0; i <= k; i+=2) { if (j == 6) { parts = 'left'; } else { parts = 'topLeft'; } id = this.id + '_card' + j + '_' + i; if (this.cardOpen) { tmp = this.pyramidCard[l]; num = tmp % 100; suit = Math.floor(tmp / 100); l++; this.card.view(id, num, suit, parts); id = this.id + '_card' + j + '_' + (i + 1); if (j == 6) { parts = 'right'; } else { parts = 'topRight'; } this.card.view(id, num, suit, parts); } else { this.card.view(id, -1, 0, parts); id = this.id + '_card' + j + '_' + (i + 1); if (j == 6) { parts = 'right'; } else { parts = 'topRight'; } this.card.view(id, -1, 0, parts); } } k += 2; } this.card.noneView(this.id + '_cast', this.bgColor); this.card.view(this.id + '_hand', -1); var node = document.getElementById(this.id + '_rest'); node.firstChild.nodeValue = this.handCard.length; } // ピラミッド:フィールドのセット Pyramid.prototype.fieldSet = function() { this.card.clear(this.id); var node; node = document.getElementById(this.id); var i, str; var nTable, nTbody, nTr, nTd, nP, nDiv, nSpan; var nTable2, nTbody2, nTr2, nTd2; nTable = document.createElement('table'); nTable.cellPadding = this.size * 2; nTable.style.backgroundColor = this.bgColor; nTbody = document.createElement('tbody'); nTr = document.createElement('tr'); nTd = document.createElement('td'); nTd.rowSpan = 2; nTable2 = document.createElement('table'); nTable2.cellPadding = 0, nTable2.cellSpacing = 0; nTbody2 = document.createElement('tbody'); for (i = 0; i < 7; i++) { nTbody2.appendChild(this.fieldSet2('cardTable', i)); } nTable2.appendChild(nTbody2); nTd.appendChild(nTable2); nTr.appendChild(nTd); nTd = document.createElement('td'); nTd.vAlign = 'top'; nTd.style.fontSize = this.fontSize + 'pt'; nTd.style.lineHeight = this.lineHeight + 'pt'; nP = document.createElement('p'); nP.align = 'right'; nP.style.color = 'black'; nP.appendChild(document.createTextNode('点数 ')); nSpan = document.createElement('span'); nSpan.id = this.id + '_point'; nSpan.style.fontWeight = 'bold'; nSpan.appendChild(document.createTextNode('0')); nP.appendChild(nSpan); nP.appendChild(document.createTextNode('点')); nP.appendChild(document.createElement('br')); nSpan = document.createElement('span'); nSpan.id = this.id + '_button_mode'; nSpan.onclick = this.click; if (this.cardOpen) { str = '《オープンモード》'; } else { str = '《通常モード》'; } nSpan.appendChild(document.createTextNode(str)); nP.appendChild(nSpan); nTd.appendChild(nP); nTr.appendChild(nTd); nTbody.appendChild(nTr); nTr = document.createElement('tr'); nTd = document.createElement('td'); nTd.align = 'center', nTd.vAlign = 'bottom'; nTd.style.fontSize = this.fontSize + 'pt'; nP = document.createElement('p'); nP.id = this.id + '_button'; nTd.appendChild(nP); nP = document.createElement('p'); nP.align = 'right'; nP.style.color = 'black'; nP.appendChild(document.createTextNode('山札残り ')); nSpan = document.createElement('span'); nSpan.id = this.id + '_rest'; nSpan.style.fontWeight = 'bold'; nSpan.appendChild(document.createTextNode('24')); nP.appendChild(nSpan); nP.appendChild(document.createTextNode('枚')); nTd.appendChild(nP); nTable2 = document.createElement('table'); nTable2.cellPadding = 0, nTable2.cellSpacing = 0; nTbody2 = document.createElement('tbody'); nTr2 = document.createElement('tr'); nTd2 = document.createElement('td'); nDiv = document.createElement('div'); nDiv.id = this.id + '_cast'; nDiv.style.marginRight = this.size * 2 + 'pt'; nDiv.onclick = this.click; nTd2.appendChild(nDiv); nTr2.appendChild(nTd2); nTd2 = document.createElement('td'); nDiv = document.createElement('div'); nDiv.id = this.id + '_hand'; nDiv.onclick = this.click; nTd2.appendChild(nDiv); nTr2.appendChild(nTd2); nTbody2.appendChild(nTr2); nTable2.appendChild(nTbody2); nTd.appendChild(nTable2); nTr.appendChild(nTd); nTbody.appendChild(nTr); nTable.appendChild(nTbody); node.appendChild(nTable); } // ピラミッド:フィールドのセット2 Pyramid.prototype.fieldSet2 = function(element, option) { var i, num, id, str; var elm, nTd, nTable2, nTbody2, nTr2, nTd2; if (element == 'cardTable') { num = (option + 1) * 2; elm = document.createElement('tr'); nTd = document.createElement('td'); nTable2 = document.createElement('table'); nTable2.cellPadding = 0, nTable2.cellSpacing = 0; nTable2.align = 'center'; nTbody2 = document.createElement('tbody'); nTr2 = document.createElement('tr'); for (i = 0; i < num; i++) { nTd2 = document.createElement('td'); nTd2.id = this.id + '_card' + option + '_' + i; nTd2.onclick = this.click; nTd2.vAlign = 'top'; nTr2.appendChild(nTd2); } nTbody2.appendChild(nTr2); nTable2.appendChild(nTbody2); nTd.appendChild(nTable2); elm.appendChild(nTd); } else if (element == 'button') { id = this.id + '_button_'; elm = document.createElement('div'); elm.id = id + option; elm.style.marginBottom = '5pt'; elm.style.border = '2pt double black'; if (this.ie) { elm.style.cursor = 'hand'; } else { elm.style.cursor = 'pointer'; } elm.style.color = 'black'; elm.onclick = this.click; if (option == 'start') { str = 'ゲーム開始'; } else if (option == 'giveUp') { str = 'ギブアップ'; } else if (option == 'reuse') { str = '山札の再利用'; } elm.appendChild(document.createTextNode(str)); } return elm; } // ピラミッド:ボタンのセット Pyramid.prototype.buttonSet = function(str) { this.card.clear(this.id + '_button'); var node = document.getElementById(this.id + '_button'); if (str == 'start') { node.appendChild(this.fieldSet2('button', 'start')); } else if (str == 'giveUp') { node.appendChild(this.fieldSet2('button', 'giveUp')); } else if (str == 'reuse') { node.appendChild(this.fieldSet2('button', 'giveUp')); node.appendChild(this.fieldSet2('button', 'reuse')); } else if (str == '') { } } // ピラミッド:カーソルのセット Pyramid.prototype.cursorSet = function(id1, id2) { var id, node; if (id1 == 'cast' || id1 == 'hand') { id = this.id + '_' + id1; } else { id = this.id + '_card' + id1 + '_' + id2; } node = document.getElementById(id); if (this.ie) { node.style.cursor = 'hand'; } else { node.style.cursor = 'pointer'; } } // ピラミッド:カーソルのクリア Pyramid.prototype.cursorClear = function(id1, id2) { var id = this.id + '_card', id2, node; var i, j, k; if (id1 == null || id1 == '') { for (j = 0; j < 7; j++) { k = (j + 1) * 2; if (k == 2) { k = 1; } for (i = 0; i < k; i++) { id2 = id + j + '_' + i; node = document.getElementById(id2); node.style.cursor = 'default'; } } node = document.getElementById(this.id + '_cast'); node.style.cursor = 'default'; node = document.getElementById(this.id + '_hand'); node.style.cursor = 'default'; } else if (id1 == 'cast' || id1 == 'hand') { id = this.id + '_' + id1; node = document.getElementById(id); node.style.cursor = 'default'; } else { node = document.getElementById(id + id1 + '_' + id2); node.style.cursor = 'default'; } } // ピラミッド:一組のカードを準備 Pyramid.prototype.oneCardsSet = function() { this.oneCards = new Array(); var i, j, k = 0; for (j = 0; j < 4; j++) { for (i = 1; i <= 13; i++) { this.oneCards[k] = (j * 100) + i; k++; } } this.oneCards = shuffle(this.oneCards); } // ピラミッド:山札を一枚めくる Pyramid.prototype.cardHit = function() { var tmp, num, suit; this.castCard[this.castCard.length] = this.handCard[0]; this.cardSelChange('none'); tmp = this.handCard[0]; num = tmp % 100; suit = Math.floor(tmp / 100); this.card.view(this.id + '_cast', num, suit); this.handCard = this.handCard.slice(1); this.restView(this.handCard.length); if (this.handCard.length == 0) { this.cursorClear('hand'); this.card.noneView(this.id + '_hand', this.bgColor); if (this.handUse < 3) { this.buttonSet('reuse'); } } if (this.castCard.length == 1) { this.cursorSet('cast'); } } // ピラミッド:カードの選択 Pyramid.prototype.cardSelChange = function(card) { var i, j, tmp, num, suit, id, id1, id2; var dNum = new Array(0, 1, 3, 6, 10, 15, 21); if (this.check > 0) { this.check = 0; if (this.castState > 2 && this.castCard.length > 0) { this.castState = 2; tmp = this.castCard[this.castCard.length - 1]; num = tmp % 100; suit = Math.floor(tmp / 100); this.card.view(this.id + '_cast', num, suit); } for (i = 0; i < 28; i++) { if (this.cardState[i] < 3) { continue; } tmp = this.pyramidCard[i]; num = tmp % 100; suit = Math.floor(tmp / 100); for (j = 6; j >= 0; j--) { if (dNum[j] <= i) { id1 = j, id2 = (i - dNum[j]) * 2; break; } } this.cardState[i] = 2; id = this.id + '_card' + id1 + '_' + id2; if (id1 == 6) { this.card.view(id, num, suit, 'left'); id = this.id + '_card' + id1 + '_' + (id2 + 1); this.card.view(id, num, suit, 'right'); } else { this.card.view(id, num, suit, 'topLeft'); id = this.id + '_card' + id1 + '_' + (id2 + 1); this.card.view(id, num, suit, 'topRight'); id1++; id = this.id + '_card' + id1 + '_' + (id2 + 1); this.card.view(id, num, suit, 'bottomLeft'); id = this.id + '_card' + id1 + '_' + (id2 + 2); this.card.view(id, num, suit, 'bottomRight'); } } } if (card != 'none') { if (card == 'cast') { this.castState = 3; tmp = this.castCard[this.castCard.length - 1]; num = tmp % 100; suit = Math.floor(tmp / 100); this.check = num; this.cardSelect[0].view(this.id + '_cast', num, suit); } else { this.cardState[card] = 3; tmp = this.pyramidCard[card]; num = tmp % 100; suit = Math.floor(tmp / 100); this.check = num; for (i = 6; i >= 0; i--) { if (dNum[i] <= card) { id1 = i, id2 = (card - dNum[i]) * 2; break; } } id = this.id + '_card' + id1 + '_' + id2; if (id1 == 6) { this.cardSelect[0].view(id, num, suit, 'left'); id = this.id + '_card' + id1 + '_' + (id2 + 1); this.cardSelect[0].view(id, num, suit, 'right'); } else { this.cardSelect[0].view(id, num, suit, 'topLeft'); id = this.id + '_card' + id1 + '_' + (id2 + 1); this.cardSelect[0].view(id, num, suit, 'topRight'); id1++; id = this.id + '_card' + id1 + '_' + (id2 + 1); this.cardSelect[0].view(id, num, suit, 'bottomLeft'); id = this.id + '_card' + id1 + '_' + (id2 + 2); this.cardSelect[0].view(id, num, suit, 'bottomRight'); } } if (this.castState == 2 && this.castCard.length > 0) { tmp = this.castCard[this.castCard.length - 1]; num = tmp % 100; suit = Math.floor(tmp / 100); if (num + this.check == 13) { this.castState = 4; id = this.id + '_cast'; this.cardSelect[1].view(id, num, suit); } } for (i = 0; i < 28; i++) { if (this.cardState[i] != 2) { continue; } tmp = this.pyramidCard[i]; num = tmp % 100; suit = Math.floor(tmp / 100); if (num + this.check != 13) { continue; } for (j = 6; j >= 0; j--) { if (dNum[j] <= i) { id1 = j, id2 = (i - dNum[j]) * 2; break; } } this.cardState[i] = 4; id = this.id + '_card' + id1 + '_' + id2; if (id1 == 6) { this.cardSelect[1].view(id, num, suit, 'left'); id = this.id + '_card' + id1 + '_' + (id2 + 1); this.cardSelect[1].view(id, num, suit, 'right'); } else { this.cardSelect[1].view(id, num, suit, 'topLeft'); id = this.id + '_card' + id1 + '_' + (id2 + 1); this.cardSelect[1].view(id, num, suit, 'topRight'); id1++; id = this.id + '_card' + id1 + '_' + (id2 + 1); this.cardSelect[1].view(id, num, suit, 'bottomLeft'); id = this.id + '_card' + id1 + '_' + (id2 + 2); this.cardSelect[1].view(id, num, suit, 'bottomRight'); } } } } // ピラミッド:カードの取得 Pyramid.prototype.getCard = function(card) { var i, num; if (card == 'cast') { num = this.castCard[this.castCard.length - 1] % 100; this.deleteCard('cast'); } else { num = this.pyramidCard[card] % 100; this.deleteCard(card); } if (num != 13) { if (this.castState == 3) { this.deleteCard('cast'); } else { for (i = 0; i < 28; i++) { if (this.cardState[i] == 3) { this.deleteCard(i); break; } } } } this.cardSelChange('none'); if (this.cardState[0] == 0) { alert('成功!'); this.pointCtrl(this.handCard.length); this.handUse = 0; this.cardInit(); this.cardSetInit(); this.buttonSet('start'); this.mode = 'start'; } } // ピラミッド:カードの消去 Pyramid.prototype.deleteCard = function(card) { var i, tmp, num, suit; if (card == 'cast') { this.castState = 2; this.castCard = this.castCard.slice(0, this.castCard.length - 1); if (this.castCard.length == 0) { this.cursorClear('cast'); this.card.noneView(this.id + '_cast', this.bgColor); } else { tmp = this.castCard[this.castCard.length - 1]; num = tmp % 100; suit = Math.floor(tmp / 100); this.card.view(this.id + '_cast', num, suit); } } else { var dNum = new Array(21, 15, 10, 6, 3, 1, 0); this.cardState[card] = 0; for (i = 0; i < 7; i++) { if (dNum[i] <= card) { this.pointCtrl((i + 1) * 3); break; } } dNum = new Array(0, 1, 3, 6, 10, 15, 21); var id, id1, id2; var leftCard, rightCard, topLeftCard, topRightCard; for (i = 6; i >= 0; i--) { if (dNum[i] <= card) { id1 = i, id2 = (card - dNum[i]) * 2; if (card == dNum[i]) { leftCard = -1, topLeftCard = -1; } else { leftCard = card - 1; topLeftCard = dNum[id1 - 1]; tmp = id2 - 1; topLeftCard += Math.floor(tmp / 2); } if (card == dNum[i] + i) { rightCard = -1, topRightCard = -1; } else { rightCard = card + 1; topRightCard = dNum[id1 - 1]; topRightCard += Math.floor(id2 / 2); } break; } } var parts; this.pyramidCard[card] = 0; id = this.id + '_card' + id1 + '_' + id2; this.cursorClear(id1, id2); if (id1 != 6) { this.cursorClear(id1 + 1, id2 + 1); } if (leftCard == -1) { if (id1 == 6) { parts = 'left'; } else { parts = 'topLeft'; } this.card.noneView(id, this.bgColor, parts); } else if (this.cardState[leftCard] == 0) { this.cardState[topLeftCard] = 2; tmp = this.pyramidCard[topLeftCard]; num = tmp % 100; suit = Math.floor(tmp / 100); this.card.view(id, num, suit, 'bottomRight'); this.cursorSet(id1, id2); id = this.id + '_card' + id1 + '_' + (id2 - 1); this.card.view(id, num, suit, 'bottomLeft'); this.cursorSet(id1, id2 - 1); id = this.id + '_card' + (id1 - 1) + '_' + (id2 - 1); this.card.view(id, num, suit, 'topRight'); this.cursorSet(id1 - 1, id2 - 1); id = this.id + '_card' + (id1 - 1) + '_' + (id2 - 2); this.card.view(id, num, suit, 'topLeft'); this.cursorSet(id1 - 1, id2 - 2); } else { if (this.cardOpen) { tmp = this.pyramidCard[topLeftCard]; num = tmp % 100; suit = Math.floor(tmp / 100); this.card.view(id, num, suit, 'bottomRight'); } else { this.card.view(id, -1, 0, 'bottomRight'); } } id = this.id + '_card' + id1 + '_' + (id2 + 1); this.cursorClear(id1, id2 + 1); if (id1 != 6) { this.cursorClear(id1 + 1, id2 + 2); } if (rightCard == -1) { if (id1 == 6) { parts = 'right'; } else { parts = 'topRight'; } this.card.noneView(id, this.bgColor, parts); } else if (this.cardState[rightCard] == 0) { this.cardState[topRightCard] = 2; tmp = this.pyramidCard[topRightCard]; num = tmp % 100; suit = Math.floor(tmp / 100); this.card.view(id, num, suit, 'bottomLeft'); this.cursorSet(id1, id2 + 1); id = this.id + '_card' + id1 + '_' + (id2 + 2); this.card.view(id, num, suit, 'bottomRight'); this.cursorSet(id1, id2 + 2); id = this.id + '_card' + (id1 - 1) + '_' + id2; this.card.view(id, num, suit, 'topLeft'); this.cursorSet(id1 - 1, id2); id = this.id + '_card' + (id1 - 1) + '_' + (id2 + 1); this.card.view(id, num, suit, 'topRight'); this.cursorSet(id1 - 1, id2 + 1); } else { if (this.cardOpen) { tmp = this.pyramidCard[topRightCard]; num = tmp % 100; suit = Math.floor(tmp / 100); this.card.view(id, num, suit, 'bottomLeft'); } else { this.card.view(id, -1, 0, 'bottomLeft'); } } if (id1 != 6) { id = this.id + '_card' + (id1 + 1) + '_' + (id2 + 1); this.card.noneView(id, this.bgColor, 'topLeft'); id = this.id + '_card' + (id1 + 1) + '_' + (id2 + 2); this.card.noneView(id, this.bgColor, 'topLeft'); } } } // ピラミッド:山札の残り枚数表示 Pyramid.prototype.restView = function(num) { var node = document.getElementById(this.id + '_rest'); node.firstChild.nodeValue = num; } // ピラミッド:点数の操作 Pyramid.prototype.pointCtrl = function(num) { this.point += num; var node = document.getElementById(this.id + '_point'); node.firstChild.nodeValue = this.point; var over; if (this.pointCheck == 0) { over = 500; } else { over = this.pointCheck * 1000; } if (this.point >= over) { alert(over + '点突破!'); this.pointCheck++; } } // ピラミッド:クリック Pyramid.prototype.click = function() { var click = this.id, cP = cardPyramid; var i, j, tmp, id, num, suit; if (click.match(/button/)) { click = click.replace(cP.id + '_button_', ''); if (click == 'start') { cP.buttonSet('giveUp'); for (i = 0; i < 7; i++) { cP.cardState[21 + i] = 3; cP.cursorSet(6, i * 2); cP.cursorSet(6, (i * 2) + 1); } cP.check = 1; cP.cardSelChange('none'); cP.cardHit(); cP.cursorSet('hand'); cP.mode = 'play'; } else if (click == 'giveUp') { id = cP.id + '_button_mode'; node = document.getElementById(id); cP.handUse = 0; cP.cardInit(); cP.cardSetInit(); cP.buttonSet('start'); cP.mode = 'start'; } else if (click == 'reuse') { cP.buttonSet('giveUp'); this.handUse++; cP.pointCtrl(-10); cP.handCard = cP.castCard; cP.castCard = new Array(); cP.cursorClear('cast'); cP.card.noneView(cP.id + '_cast', cP.bgColor); cP.card.view(cP.id + '_hand', -1); cP.cursorSet('hand'); cP.cardHit(); } else if (click == 'mode') { if (cP.mode != 'play') { return; } id = cP.id + '_button_mode'; var node = document.getElementById(id); if (cP.cardOpen) { cP.cardOpen = false; node.firstChild.nodeValue = '《通常モード》'; } else { cP.cardOpen = true; node.firstChild.nodeValue = '《オープンモード》'; } } } else if (click.match(/hand/)) { if (cP.mode != 'play') { return; } else if (cP.handCard.length == 0) { return; } cP.cardHit(); } else if (click.match(/cast/)) { if (cP.mode != 'play') { return; } else if (cP.castCard.length == 0) { return; } num = cP.castCard[cP.castCard.length - 1] % 100; if (num == 13) { cP.getCard('cast'); } else if (cP.castState == 2) { cP.cardSelChange('cast'); } else if (cP.castState == 3) { cP.cardSelChange('none'); } else if (cP.castState == 4) { cP.getCard('cast'); } } else { if (cP.mode != 'play') { return; } click = click.replace(cP.id + '_card', ''); tmp = click.split('_'); var dNum = new Array(0, 1, 3, 6, 10, 15, 21); var pCard = dNum[tmp[0]] + Math.floor(tmp[1] / 2); if (tmp[1] != 0 && tmp[1] != (tmp[0] * 2) + 1) { if (cP.cardState[pCard] == 0) { tmp[0]--, tmp[1]--; pCard = dNum[tmp[0]] + Math.floor(tmp[1] / 2); } } num = cP.pyramidCard[pCard] % 100; if (cP.cardState[pCard] == 0 || cP.cardState[pCard] == 1) { return; } else if (num == 13) { cP.getCard(pCard); } else if (cP.cardState[pCard] == 2) { cP.cardSelChange(pCard); } else if (cP.cardState[pCard] == 3) { cP.cardSelChange('none'); } else if (cP.cardState[pCard] == 4) { cP.getCard(pCard); } } } // シャッフル(配列のランダムソート) function shuffle(ary) { var i, cut, len = ary.length, ary1, ary2, resultAry = new Array(); for (i = 0; i < len; i++) { cut = dice(1, ary.length); if (ary.length == 1) { resultAry[i] = ary[0]; } else { resultAry[i] = ary[cut-1]; ary1 = ary.slice(0, cut-1); ary2 = ary.slice(cut); ary = ary1.concat(ary2); } } return resultAry; } // ダイスロール function dice(num, dice) { num = naturalNumCheck(num); dice = naturalNumCheck(dice, 6); var i, result = 0; for (i = 0; i < num; i++) { result += Math.ceil(Math.random() * dice); } return result; } // 自然数チェック function naturalNumCheck(checkNum, returnNum) { checkNum -= 0, returnNum -= 0; if (returnNum < 1 || returnNum == null || isNaN(returnNum)) { returnNum = 1; } if (checkNum < 1 || checkNum == null || isNaN(checkNum)) { return returnNum; } else { return checkNum; } }