Skip to content

Instantly share code, notes, and snippets.

@naosim
Last active May 1, 2020 21:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naosim/8e31f675ce2a5848dbb4af702d274fa9 to your computer and use it in GitHub Desktop.
Save naosim/8e31f675ce2a5848dbb4af702d274fa9 to your computer and use it in GitHub Desktop.
1次元オセロのお題
<!DOCTYPE html>
<meta charset="utf-8" />
<script>
/**
* 1次元オセロの盤面に白の石を置く
*
* - 盤は配列で表現する
* - 白の石は'白'
* - 黒の石は'黒'
* - 空の場所はnull
*
* [null, '黒', '白', '黒', null, '黒', '黒', '白']
* @param {number} diskIndex 白の石を置く場所
* @param {string[]} board 盤。各要素には'白'または'黒'またはnullが入っている。nullは空の意味。
* @returns {string[]} 白の石を置いた時に、オセロのルールにしたがって黒が白にひっくり返った盤面を返す。置けない場所に置かれた場合は盤面をそのまま返す。
*/
function putLightDisk(diskIndex, board) {
// 事前条件
if(!isInArrayRange(diskIndex, board)) {
throw new Error('盤面外の座標が指定されています');
}
// 指定した場所に既に石があるならそのまま返す
if(board[diskIndex] !== null) {
return board;
}
var currentDiskColor = '白';
var otherDiskColor = '黒';
// 右方向にある自分の色の石、または、空の位置を取得する
var limitIndex = getCurrentColorOrEmptyIndexToRight(diskIndex, otherDiskColor, board);
if(limitIndex !== undefined && board[limitIndex] == currentDiskColor) {
board[diskIndex] = currentDiskColor; // 石を置く
flipWithRange(diskIndex, limitIndex, currentDiskColor, board);// diskIndexからlimitIndexまでをひっくり返す
}
// 左方向にある自分の色の石、または、空の位置を取得する
var limitIndex = getCurrentColorOrEmptyIndexToLeft(diskIndex, otherDiskColor, board);
if(limitIndex !== undefined && board[limitIndex] == currentDiskColor) {
board[diskIndex] = currentDiskColor; // 石を置く
flipWithRange(diskIndex, limitIndex, currentDiskColor, board);// diskIndexからlimitIndexまでをひっくり返す
}
return board;
}
/**
* iが配列の範囲内かどうか
* @param {number} i
* @param {Array} ary
*/
function isInArrayRange(i, ary) {
return i >= 0 && i < ary.length;
}
/**
* 右方向にある自分の色の石、または、空の位置を取得する
* @param {number} diskIndex
* @param {string} otherDiskColor '白'または'黒'
* @param {string[]} board
* @returns {number} 自分の色の石、または、空の位置。見つからない場合はundefined。
*/
function getCurrentColorOrEmptyIndexToRight(
diskIndex,
otherDiskColor,
board
) {
var i = diskIndex + 1;
while(true) {
if(!isInArrayRange(i, board)) {
return undefined;
}
if(board[i] != otherDiskColor) {
return i;
}
i++;
}
}
/**
* 左方向にある自分の色の石、または、空の位置を取得する
* @param {number} diskIndex
* @param {string} otherDiskColor '白'または'黒'
* @param {string[]} board
* @returns {number} 自分の色の石、または、空の位置。見つからない場合はundefined。
*/
function getCurrentColorOrEmptyIndexToLeft(
diskIndex,
otherDiskColor,
board
) {
var i = diskIndex - 1;
while(true) {// returnで
if(!isInArrayRange(i, board)) {
return undefined;
}
if(board[i] != otherDiskColor) {
return i;
}
i--;
}
}
/**
* 範囲内にある石をひっくり返す
*
* @param {number} fromIndexExcluded 開始位置。境界値含まず。
* @param {number} toIndexExcluded 終了位置。境界値含まず。開始位置より小さい値でもok
* @param {string} currentDiskColor '白'または'黒'
* @param {string[]} board
*/
function flipWithRange(fromIndexExcluded, toIndexExcluded, currentDiskColor, board) {
var min = Math.min(fromIndexExcluded, toIndexExcluded);
var max = Math.max(fromIndexExcluded, toIndexExcluded);
for(var i = min + 1; i < max; i++) {
board[i] = currentDiskColor;
}
}
// 実行
// ひっくり返えるパタン 右
var result1 = putLightDisk(0, [null, '黒', '白', '黒', null, '黒', '黒', '白']);
console.log(result1);// ['白', '白', '白', '黒', null, '黒', '黒', '白']
// ひっくり返えるパタン 左右
var result2 = putLightDisk(4, [null, '黒', '白', '黒', null, '黒', '黒', '白']);
console.log(result2);// [null, '黒', '白', '白', '白', '白', '白', '白']
// ひっくり返らないパタン
var result3 = putLightDisk(0, [null, null, '白', '白', '黒', '黒', '黒', null]);
console.log(result3);// [null, null, '白', '白', '黒', '黒', '黒', null];
</script>
<!DOCTYPE html>
<meta charset="utf-8" />
<script>
/**
* 1次元オセロの盤面に白の石を置く
*
* - 盤は配列で表現する
* - 白の石は'白'
* - 黒の石は'黒'
* - 空の場所はnull
*
* [null, '黒', '白', '黒', null, '黒', '黒', '白']
* @param {number} diskIndex 白の石を置く場所
* @param {string[]} board 盤。各要素には'白'または'黒'またはnullが入っている。nullは空の意味。
* @returns {string[]} 白の石を置いた時に、オセロのルールにしたがって黒が白にひっくり返った盤面を返す。置けない場所に置かれた場合は盤面をそのまま返す。
*/
function putLightDisk(diskIndex, board) {
// TODO 実装
return null; // ここにひっくり返った後の配列を返す
}
// 実行
// ひっくり返えるパタン 右
var result1 = putLightDisk(0, [null, '黒', '白', '黒', null, '黒', '黒', '白']);
console.log(result1);// ['白', '白', '白', '黒', null, '黒', '黒', '白']
// ひっくり返えるパタン 左右
var result2 = putLightDisk(4, [null, '黒', '白', '黒', null, '黒', '黒', '白']);
console.log(result2);// [null, '黒', '白', '白', '白', '白', '白', '白']
// ひっくり返らないパタン
var result3 = putLightDisk(0, [null, null, '白', '白', '黒', '黒', '黒', null]);
console.log(result3);// [null, null, '白', '白', '黒', '黒', '黒', null];
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment