始めから読む  [目次]  [STEP0]  [STEP1]  [STEP2]  [STEP3]  [STEP4]  [STEP5]  [STEP6]  [STEP7]  [終わりに]

猫でも作れる神経衰弱♪

終わりに

 この講座の終わりに、この機会にゲームデザイナーへの道を歩き始めようって思った人のために、この神経衰弱を自由に改造するためのヒントをいくつか紹介しますにゃ。

・画像や文字の表示、画面の色などを変える
 初心者さんは、ここから始めるといいですにゃ。ちょっと変えるだけで、ゲームの雰囲気ががらっと変わることもありますにゃ。
・コンピュータがカードを覚える確率、カードを忘れる最大数を変える
 関数commemoryと関数comforgetの中をちょっと書き換えるだけでできますにゃ。この講座では、覚える確率と忘れる最大枚数を計算式で作ったんですけど、「if player[i]==??」をコンピュータの人数分作って、その中で変数aの値を決めれば、コンピュータごとにまったく別の値を設定することもできますにゃ。例えば「物覚えは悪いけど1回覚えたら忘れにゃい」など、コンピュータごとに性格のようなものを持たせることもできますにゃ。
・コンピュータの人数を増やす
 これも簡単にできますにゃ。その場合は、bodyの中にあるselectのoptionも増やす必要がありますにゃ。
・カードの枚数や種類を増やす
 これは、カードの画像を増やすだけじゃにゃくて、配列の最大値やループの回数も変更しにゃいといけませんから、中級者さん向きかもしれませんにゃ。でも、やろうと思えばできますにゃ。
・ジョーカー(またはその役割をするカード)を使う
 カードが揃ったかどうかの判定を書き換えれば、ジョーカーと別のカードの組み合わせて「揃った」と判定させることはできますにゃ。ただし、1枚目にめくったカードがジョーカーだったら、2枚目がどんなカードでも必ず揃ってしまうことになりますから、そのあたりは例えば「2枚目がジョーカーだった時」など、ルールを調整したほうがいいかもしれませんにゃ。また、「ジョーカーとある数字」「ジョーカーと別の数字」で揃えて取った場合は、最後に揃わにゃいカードが2枚残ることになるんですけど、「ジョーカーとある数字」「ジョーカーとさっきとおなじ数字」または「ジョーカー2枚」で揃えて取った場合は、揃わにゃいで残るカードはありませんにゃ。そのあたりの調整も必要になってきますにゃ。
・ラッキーカードを「表示されたカードの次の数字」にして、表示されたカードが実際に1枚減るようにする
 麻雀が好きな人におすすめの改造ですにゃ。今のルールとおなじようにラッキーカードを1から7までに限定して、7の次は1とするのが普通だと思うんですけど、0やくるくるカードも含めるというのも面白い考え方ですにゃ。
・人間対コンピュータで、最初はLv1しか選択できにゃくて、勝つと次のレベルに挑戦できるようにする
 前のレベルのコンピュータに勝った(または1回も勝っていない)という情報を、変数として「関数mainの外側に」書く必要がありますにゃ。関数mainの中に書いてしまうと、ゲームごとに情報がリセットされてしまいますにゃ。「3回勝ったら」「5戦以上で勝ち越したら」など、いろいろ工夫できるかもしれませんにゃ。
・2枚じゃにゃくて3枚のカードをめくって揃えるルールにする
 プログラムのいろんなところをがらっと変えにゃいといけませんから、上級者さん向けの改造になりますにゃ。コンピュータの思考ルーチンも複雑になってきますにゃ。
・3枚のカードで「123」などの連番でも取れるようにして、さらにジョーカーを…
 そこまでする必要があるのかどうかわかりませんけど、やろうと思えばできますにゃ。他にもいろんな考え方があって、いろいろ改造できると思いますから、あなたご自身がいろいろ考えてみてくださいにゃ。

 最後に付録として、この講座で作ったプログラムの完成版を、そのまま載せさせていただきますにゃ。
<html>
<head>
<title>神経衰弱♪</title>
<script language="JavaScript">
<!--
tims=0;times=0;flg=0;
var player=new Array(2);var p=new Array(30);var score=new Array(2);
var cp=new Array(60);var cpp=new Array(10);
var gz=new Array(11);
for (i=0;i<=10;i++) {gz[i]=new Image(48,60);}
for (i=0;i<=10;i++) {gz[i].src="./card-"+i+".gif";}

// メイン
function main()
{
 player[0]=document.hyoji.player1.value*1;
 player[1]=document.hyoji.player2.value*1;
 gametype=document.hyoji.gmt.value*1;
 lcrule=document.hyoji.lc.value*1;
 for (i=0;i<=6;i++)
 {
  for (j=0;j<=3;j++)
  {
   p[i*4+j]=i+1;
  }
 }
 p[28]=8;p[29]=8;
 if (gametype==1) {p[28]=9;p[29]=9;}
 if (gametype==2) {p[28]=8;p[29]=9;}
 if (gametype==3)
 {
  for (i=0;i<=2;i++)
  {
   r1=Math.floor(Math.random()*7)+1;
   r2=Math.floor(Math.random()*7)+1;
   if (r1==r2) {i=0;}
   else {p[28]=r1;p[29]=r2;break;}
  }
 }
 h=cardmix();
// h=carddataput();
 h=ruleinfo();
 if (lcrule>=1)
 {
  luckycard=Math.floor(Math.random()*7)+1;
 }
 else {luckycard=10;}
 h=charaput(30,luckycard);
 document.hyoji.tm.value="0分0秒";
 document.hyoji.sc1.value="0点";document.hyoji.sc2.value="0点";
 document.hyoji.h1.value="【先攻】の番ですにゃ";
 if (player[0]==0) {c="1枚目のカードをクリックしてくださいにゃ";} else {c="";}
 document.hyoji.h2.value=c;
 if (gametype<=1) {cardkazu=30;} else {cardkazu=28;}
 teban=0;cardnum1=-1;cardnum2=-1;score[0]=0;score[1]=0;
 tims=0;times=0;flg=1;
 if (player[0]>0) {h=complay1();}
}

// カードシャッフル
function cardmix()
{
 for (i=0;i<=999;i++)
 {
  r1=Math.floor(Math.random()*30);
  r2=Math.floor(Math.random()*30);
  a=p[r1];p[r1]=p[r2];p[r2]=a;
 }
 for (i=0;i<=29;i++)
 {
  if (p[i]==0) {a=0;} else {a=10;}
  h=charaput(i,a);
 }
 for (i=0;i<=59;i++) {cp[i]=0;}
}

// マウスクリック処理
function pic(n)
{
 if (flg==1 && player[teban]==0)
 {
  if (p[n]>0)
  {
   h=charaput(n,p[n]);
   cardnum1=n;
   flg=2;wait=0;
  }
 }
 if (flg==3 && player[teban]==0)
 {
  if (p[n]>0 && n!=cardnum1)
  {
   h=charaput(n,p[n]);
   cardnum2=n;
   h=hantei();
  }
 }
}

// カード獲得判定
function hantei()
{
 if (p[cardnum1]==9 || p[cardnum2]==9) {kuru=1;} else {kuru=0;}
 if (p[cardnum1]==p[cardnum2])
 {
  c="あたりにゃ♪";
  score[teban]=score[teban]+1;
  if (p[cardnum1]==luckycard)
  {
   c="ラッキーカードであたりにゃ♪";
   score[teban]=score[teban]+lcrule;
  }
  document.hyoji.sc1.value=score[0]+"点";
  document.hyoji.sc2.value=score[1]+"点";
  cardkazu=cardkazu-2;
  p[cardnum1]=0;p[cardnum2]=0;
  cp[cardnum1]=0;cp[cardnum1+30]=0;
  cp[cardnum2]=0;cp[cardnum2+30]=0;
 }
 else
 {
  c="はずれにゃ…";
  h=commemory();
 }
 document.hyoji.h2.value=c;
 if (cardkazu<=0)
 {
  document.hyoji.h1.value="ゲーム終了にゃ♪";
  document.hyoji.h2.value="[開始]をクリックするともう1回遊べるのにゃ";
  flg=0;
 }
 else
 {
  h=comforget();
  wait=10;flg=4;
 }
}

// カードの内容表示
function carddataput()
{
 c="";
 for (i=0;i<=4;i++)
 {
  c1="";c2="";c3="";
  for (j=0;j<=5;j++)
  {
   a=i*6+j;
   c1=c1+"["+p[a]+"]";
   c2=c2+"["+cp[a]+"]";c3=c3+"["+cp[a+30]+"]";
  }
  c=c+c1+"    "+c2+"    "+c3+"\n";
 }
 document.hyoji.text1.value=c;
}

// 画像表示
function charaput(n1,n2)
{
 name="img"+n1;
 document.images[name].src=gz[n2].src;
}

// コンピュータ思考(1枚目)
function complay1()
{
 for (i=0;i<=9;i++) {cpp[i]=0;}
 for (i=0;i<=29;i++)
 {
  if (cp[i+teban*30]>0 && p[i]>0)
  {
   cpp[cp[i+teban*30]]=cpp[cp[i+teban*30]]+1;
  }
 }
 cardnum1=-1;tgn=-1;
 for (i=1;i<=9;i++)
 {
  if (cpp[i]>=2)
  {
   tgn=i;break;
  }
 }
 if (tgn>=1)
 {
  for (i=0;i<=29;i++)
  {
   if (cp[i+teban*30]==tgn)
   {
    cardnum1=i;break;
   }
  }
 }
 if (cardnum1<0)
 {
  for (i=0;i<=2;i++)
  {
   r=Math.floor(Math.random()*30);
   if (p[r]==0 || cp[r+teban*30]>0) {i=0;}
   else {cardnum1=r;break;}
  }
 }
 h=charaput(cardnum1,p[cardnum1]);
 flg=2;wait=10;
}

// コンピュータ思考(2枚目)
function complay2()
{
 cardnum2=-1;
 for (i=0;i<=29;i++)
 {
  if (cp[i+teban*30]==p[cardnum1] && p[i]>0 && i!=cardnum1)
  {
   cardnum2=i;break;
  }
 }
 if (cardnum2<0)
 {
  for (i=0;i<=2;i++)
  {
   r=Math.floor(Math.random()*30);
   if (p[r]==0 || r==cardnum1 || cp[r+teban*30]>0) {i=0;}
   else {cardnum2=r;break;}
  }
 }
 h=charaput(cardnum2,p[cardnum2]);
 h=hantei();
}

// コンピュータ記憶
function commemory()
{
 for (i=0;i<=1;i++)
 {
  if (player[i]>0)
  {
   a=player[i]*20-10;
   r=Math.floor(Math.random()*100);
   if (r<a) {cp[cardnum1+i*30]=p[cardnum1];}
   r=Math.floor(Math.random()*100);
   if (r<a) {cp[cardnum2+i*30]=p[cardnum2];}
  }
 }
}

// コンピュータ忘却
function comforget()
{
 for (i=0;i<=1;i++)
 {
  if (player[i]>0)
  {
   a=10-player[i]*2;
   for (j=0;j<a;j++)
   {
    r=Math.floor(Math.random()*30);
    cp[r+i*30]=0;
   }
  }
 }
}

// ルール説明
function ruleinfo()
{
 if (gametype==0)
 {
  c="【GAME:A】\n";
  c=c+"・数字の「1」〜「7」が各4枚、数字の「0」が2枚ありますにゃ。\n";
 }
 if (gametype==1)
 {
  c="【GAME:B】\n";
  c=c+"・数字の「1」〜「7」が各4枚、「くるくるカード」が2枚ありますにゃ。\n";
 }
 if (gametype==2)
 {
  c="【GAME:C】\n";
  c=c+"・数字の「1」〜「7」が各4枚、数字の「0」と「くるくるカード」が1枚ずつありますにゃ。\n";
 }
 if (gametype==1 || gametype==2)
 {
  c=c+"・くるくるカードをめくると、手番が終わった時に場のカードがシャッフルされますにゃ。\n";
 }
 if (gametype==3)
 {
  c="【GAME:D】\n";
  c=c+"・数字の「1」〜「7」のうち、どれか2つの数字が5枚ずつ、その他の数字が4枚ずつありますにゃ。\n";
 }
 if (lcrule>0)
 {
  c=c+"・ラッキーカードが揃った時は、";
  if (lcrule==1) {c=c+"+1点";} else {c=c+"+2点";}
  c=c+"のボーナスポイントが加算されますにゃ。\n";
 }
 if (gametype>=2)
 {
  c=c+"・最後まで揃わにゃいカードが場に2枚残ることになりますにゃ。\n";
 }
 c=c+"・その他のルールは、普通の神経衰弱とおなじですにゃ。\n";
 document.hyoji.text1.value=c;
}

// タイマー処理
function timerX()
{
 if (flg>=1)
 {
  tims=tims+1;
  if (tims%10==0)
  {
   times=times+1;
   a1=Math.floor(times/60);a2=times%60;
   document.hyoji.tm.value=""+a1+"分"+a2+"秒";
  }
 }
 if (flg==2)
 {
  wait=wait-1;
  if (wait<=0)
  {
   if (player[teban]==0) {c="2枚目のカードをクリックしてくださいにゃ";} else {c="";}
   document.hyoji.h2.value=c;
   flg=3;
   if (player[teban]>0) {h=complay2();}
  }
 }
 if (flg==4)
 {
  wait=wait-1;
  if (wait<=0)
  {
   if (p[cardnum1]==0) {a=0;} else {a=10;}
   h=charaput(cardnum1,a);h=charaput(cardnum2,a);
   cardnum1=-1;cardnum2=-1;
   if (a==10)
   {
    if (teban==0) {teban=1;c="【後攻】";}
    else {teban=0;c="【先攻】";}
    document.hyoji.h1.value=c+"の番ですにゃ";
   }
   if (kuru==1) {h=cardmix();}
//   h=carddataput();
   if (player[teban]>0) {wait=11;} else {wait=0;}
   flg=5;
  }
 }
 if (flg==5)
 {
  wait=wait-1;
  if (wait<=0)
  {
   if (player[teban]==0) {c="1枚目のカードをクリックしてくださいにゃ";} else {c="";}
   document.hyoji.h2.value=c;
   flg=1;
   if (player[teban]>0) {h=complay1();}
  }
 }
}

// -->
</script>
</head>
<body bgcolor="A0FFA0" onLoad='setInterval("timerX()",100);'>
<form name="hyoji">
<table border=1>
<tr>
<td colspan=2 bgcolor="FFC0C0">
<font size=6 color="0000FF">神経衰弱♪</font>
  <input type=button name="st1" value="開始" onClick=main()>
  <input type=text size=8 name="tm" value="0分0秒">
</td>
</tr>
<tr>
<td bgcolor="00FFFF" align=center valign=top>
<table border=0 cellspacing=0 cellpadding=0>
<tr>
<td><img name="img0" src="./card-10.gif" onClick="pic(0)"></td>
<td><img name="img1" src="./card-10.gif" onClick="pic(1)"></td>
<td><img name="img2" src="./card-10.gif" onClick="pic(2)"></td>
<td><img name="img3" src="./card-10.gif" onClick="pic(3)"></td>
<td><img name="img4" src="./card-10.gif" onClick="pic(4)"></td>
<td><img name="img5" src="./card-10.gif" onClick="pic(5)"></td>
</tr>
<tr>
<td><img name="img6" src="./card-10.gif" onClick="pic(6)"></td>
<td><img name="img7" src="./card-10.gif" onClick="pic(7)"></td>
<td><img name="img8" src="./card-10.gif" onClick="pic(8)"></td>
<td><img name="img9" src="./card-10.gif" onClick="pic(9)"></td>
<td><img name="img10" src="./card-10.gif" onClick="pic(10)"></td>
<td><img name="img11" src="./card-10.gif" onClick="pic(11)"></td>
</tr>
<tr>
<td><img name="img12" src="./card-10.gif" onClick="pic(12)"></td>
<td><img name="img13" src="./card-10.gif" onClick="pic(13)"></td>
<td><img name="img14" src="./card-10.gif" onClick="pic(14)"></td>
<td><img name="img15" src="./card-10.gif" onClick="pic(15)"></td>
<td><img name="img16" src="./card-10.gif" onClick="pic(16)"></td>
<td><img name="img17" src="./card-10.gif" onClick="pic(17)"></td>
</tr>
<tr>
<td><img name="img18" src="./card-10.gif" onClick="pic(18)"></td>
<td><img name="img19" src="./card-10.gif" onClick="pic(19)"></td>
<td><img name="img20" src="./card-10.gif" onClick="pic(20)"></td>
<td><img name="img21" src="./card-10.gif" onClick="pic(21)"></td>
<td><img name="img22" src="./card-10.gif" onClick="pic(22)"></td>
<td><img name="img23" src="./card-10.gif" onClick="pic(23)"></td>
</tr>
<tr>
<td><img name="img24" src="./card-10.gif" onClick="pic(24)"></td>
<td><img name="img25" src="./card-10.gif" onClick="pic(25)"></td>
<td><img name="img26" src="./card-10.gif" onClick="pic(26)"></td>
<td><img name="img27" src="./card-10.gif" onClick="pic(27)"></td>
<td><img name="img28" src="./card-10.gif" onClick="pic(28)"></td>
<td><img name="img29" src="./card-10.gif" onClick="pic(29)"></td>
</tr>
</table>
</td>
<td bgcolor="FFFFA0" valign=top>
先攻:
<select name="player1">
<option value=0>人間</option>
<option value=1>COM Lv1</option>
<option value=2>COM Lv2</option>
<option value=3>COM Lv3</option>
<option value=4>COM Lv4</option>
<option value=5>COM Lv5</option>
</select>
  得点:<input type=text size=4 name="sc1" value="0点"><br>
後攻:
<select name="player2">
<option value=0>人間</option>
<option value=1>COM Lv1</option>
<option value=2>COM Lv2</option>
<option value=3>COM Lv3</option>
<option value=4>COM Lv4</option>
<option value=5>COM Lv5</option>
</select>
  得点:<input type=text size=4 name="sc2" value="0点"><br>
GAME:
<select name="gmt">
<option value=0>A</option>
<option value=1>B</option>
<option value=2>C</option>
<option value=3>D</option>
</select>
  ラッキーカード:
<select name="lc">
<option value=0>なし</option>
<option value=1>+1点</option>
<option value=2>+2点</option>
</select>
<br><br>
<table border=1>
<tr>
<td align=center>
<font size=2>Lucky</font><br>
<img name="img30" src="./card-10.gif"><br>
<font size=2>Card</font>
</td>
</tr>
</table>
<br><br>
<input type=text size=40 name="h1" value="[開始]をクリックするのにゃ"><br>
<input type=text size=40 name="h2" value=""><br>
</td>
</tr>
<tr>
<td colspan=2 bgcolor="C0C0C0" align=center>
<textarea cols=80 rows=10 name="text1"></textarea>
</td>
</tr>
</table><br>
<font size=4>
あなたの名前
  <a href="http://bigchan.sakura.ne.jp/index.html">ホームページ</a>
</font>
</form>
</body>
</html>
 こんな感じでだらだらと長いだけで内容も充実してにゃい講座だったんですけど、未来のゲームデザイナーさんのために、ほんの少しでもお役に立てればと思いますにゃ。最後まで読んでいただいて、ありがとうございましたにゃ。 2020年10月 びっぐにゃん

始めから読む  [目次]  [STEP0]  [STEP1]  [STEP2]  [STEP3]  [STEP4]  [STEP5]  [STEP6]  [STEP7]  [終わりに]