昔からあるwar ship game (戦艦ゲーム)を作ってみました。
JavaScirptを学んで一か月弱になります。
C言語でできることができたり、できなかったりとなかなか苦戦しています。
ほぼほぼ基本構文を使用しており、組み込み関数をほぼ使用していないためコードが冗長になっています。
改善案をいただけると大変助かります。
デベロッパーツールを使用するゲームであり、
alartやpromptを多用しており邪魔かもしれませんが遊んでいただけると幸いです。
htmlを避けていますが、そろそろDOMについてしっかり学んで動的サイトを作りたいです。
warShipGame.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//ランダム取得関数
const getRandom =(n)=>{
return Math.floor(Math.random()*n );
};
//船設置用フィールドの初期化関数
const fieldSet =(n)=>{
array = new Array(n);
for(let x = 0; x < n; x++) {
array[x] = new Array(n);
for(let y = 0; y < n; y++) {
array[x][y] = 0;
}
}
};
//表示用フィールドの初期化関数
const myFieldSet =(n)=>{
myArray = new Array(n);
for(let x = 0; x < n; x++) {
myArray[x] = new Array(n);
for(let y = 0; y < n; y++) {
myArray[x][y] = 0;
}
}
};
//ゲームの勝利判定関数
const winGame=()=>{
let sum =0;
for(let i =0; i<shipLen;i++){
if(flag[i]==1){
sum++;
}
}
//console.log(sum);//テスト
if(sum>=3){
return 1;
}
};
//船の要素数に応じて、沈没を判定する関数
const shipEnd = ()=>{
//関数が呼ばれるたび毎回初期化
let ship1 = 0;
let ship2 = 0;
let ship3 = 0;
let len = hitArray.length;//当たり判定を格納した配列の要素数を代入
console.log(len);
for(let i =0;i<len;i++){
if(hitArray[i]==1){
ship1++;
}
if(hitArray[i]==2){
ship2++;
}
if(hitArray[i]==3){
ship3++;
}
}
if(flag[0]==1){
}
else if(ship1>=1){
alert("ship1沈没");
flag[0]=1;
}
if(flag[1]==1){
}
else if(ship2>=2){
alert("ship2沈没");
flag[1]=1;
}
if(flag[2]==1){
}
else if(ship3>=3){
alert("ship3沈没");
flag[2]=1;
}
//console.log(`${flag[0]}${flag[1]}${flag[2]}`);
};
//同じ列に船が配置されないよう検索する関数
const fieldCheck=(y)=>{
let sum = 0;
for(let i =0; i<n ; i++ ){
if(array[i][y]!=0){sum++;}
}
if(sum>0){return 1;}
return 0;
};
//船を重複しないように設置する関数
const shipSet =()=>{
//let ships=[3,2,1];
//let len = ships.length;
let cnt=0;
while( cnt< len){
let shipNum = ships[cnt];
let fie_x=getRandom(n-(shipNum-1));
let fie_y=getRandom(n);
if(fieldCheck(fie_y)==0){
array[fie_x][fie_y]=ships[cnt];
for(let i=1;i<shipNum;i++){
array[fie_x+i][fie_y]=ships[cnt];
}
cnt++;
}
}
//console.table(array);//テスト
};
//船を攻撃する関数
const attack =()=>{
//とりあえずの無理やり初期化
let y = -1;
let x = -1;
//1~5までの入力がされるまでループ
while(y<0 || x<0 || y>n-1 || x>n-1 ){
alert(`1~5までの数字を入れてください。`);
y = prompt("攻撃するx座標を選択")-1;
x = prompt("攻撃するy座標を選択")-1;
}
alert(`${y+1}${x+1}を攻撃します。`);
if(array[x][y]!=0){
alert("HIT!");
myArray[x][y]="〇";
//組込関数pusuでhitarrayに当たり判定格納
hitArray.push(array[x][y]);
shipEnd();//沈没判定
}
else{alert("MISS");
myArray[x][y]="×";
}
console.table(myArray);
//console.table(hitArray);//テスト
};
//main
alert(`遊び方:5x5のフィールドに敵の船が3隻置かれています。\n
船の大きさは1と2と3があります。勘を頼りに大砲を打ち込み\n
10回以内に全ての船を沈没させてください。`);
let n =5;//フィールドの広さ(n*n)
let cnt = 0;//ゲーム回数のカウント
let gameCount = 10;//ゲームの最大回数
let shipLen = 3;//船の数
let hitArray=[];//攻撃が当たった船番号を格納
let myArray=[];//ゲーム用フィールド
let array=[];//船設置フィールド
let flag =[];//沈没判定用
let ships=[3,2,1];
let len = ships.length;
//ゲームの初期化
fieldSet(n);
shipSet();
myFieldSet(n);
//console.table(array);//テスト
console.table(myArray);
//gameCountの数だけ攻撃
for(cnt =0;cnt<gameCount;cnt++){
alert(`残り${gameCount-cnt}回!`);
if(winGame()==1){
break;
}
attack();
}
if(winGame()==1){alert(`完全勝利`);}
else alert(`すべての船を沈められませんでした`);
console.table(array);
</script>
</body>
</html>