2021.03.31

神経衰弱

はじめに

プログラムが勝手にカードをめくっていく神経衰弱ののプログラムを作成しました。

このプログラムでは、ランダムにカードをめくっていき、全てのペア(同じ数字)が揃うと終了します。

また、1度めっくたカードは記憶しているので1枚目にオープンしたカードと同じ番号を記憶している場合は、必ずペアになるようにしています。

Javaソースコード

以下が、そのJavaソースコードです。

ShinkeiSuijaku.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
// 神経衰弱
public class ShinkeiSuijaku {
	// カードの状態を表す定数
	final static int STATUS_HIDE = 0;	// 伏せられた状態
	final static int STATUS_OPEN = 1;	// オープンの状態
	final static int STATUS_PAIR = 2;	// 揃った状態

	// カード番号を格納する配列
	static int[] cards;

	// カードの状態を格納する配列
	static int[] statuses;

	// オープンしたカードを記憶する配列
	static int[] memory;


	// カードの初期化
	private static void initCards()
	{
		// カードを格納する配列
		cards = new int[ 52 ];

		// カードを配列に格納し、シャフルする
		for ( int i = 0; i < cards.length; i++ )
			cards[ i ] = ( i / 4 ) + 1;

		for ( int i = 0; i < cards.length; ++ i ) {
			// 0~(配列cardsの個数-1)の乱数を発生
			int rnd =  (int)( Math.random() *  (double)cards.length );

			// cards[ i ]とcards[ rnd ]を入れ替える
			int w = cards[ i ];
			cards[ i ] = cards[ rnd ];
			cards[ rnd ] = w;
		}
	}


	// 状態の初期化
	private static void initStatuses()
	{
		statuses = new int[ 52 ];
		// カードの状態を"隠された状態"にする
		for ( int i = 0; i < statuses.length; i++ )
			statuses[ i ] = STATUS_HIDE;
	}


	// 記憶の初期化
	private static void initMemory()
	{
		memory = new int[ 52 ];
		for ( int i = 0; i < memory.length; i++ )
			memory[ i ] = 0;
	}


	// カードの出力
	private static void outputCards()
	{
		for ( int i = 0; i < cards.length; ++ i ) {
//			
			switch ( statuses[ i ] ) {
				case STATUS_HIDE:
					System.out.print( "*" );
					break;

				case STATUS_OPEN:
				case STATUS_PAIR:
					switch ( cards[ i ] )
					{
						case 10:
							System.out.print( "A" );
							break;
						case 11:
							System.out.print( "J" );
							break;
						case 12:
							System.out.print( "Q" );
							break;
						case 13:
							System.out.print( "K" );
							break;

						default:
							System.out.print( cards[ i ] );
							break;
					}
					break;
			}

			// カード13枚ごとに改行
			if ( 0 == ( ( i + 1 ) % 13 ) )
				System.out.println();
		}
		// 改行
		System.out.println();
	}


	// 指定した状態の数を戻す
	private static int getStatusNumber( int status  )
	{
		int number = 0;

		for ( int i = 0; i < statuses.length; i++ ) {
			if ( statuses[ i ] == status )
				++ number;
		}

		return number;
	}


	// カードを1枚オープン
	private static int openCard()
	{
		// 伏せられたカードの数を取得
		int hidenumber = getStatusNumber( STATUS_HIDE );
		if ( 1 > hidenumber ) return 0;

		// 1~hidenumberの乱数を発生
		int rnd =  (int)( Math.random() *  (double)hidenumber ) + 1;

		// 伏せられたカードのrnd番目のカードをオープン
		int cardnum = 0;
		for ( int i = 0; i < statuses.length; i++ ) {
			if ( STATUS_HIDE == statuses[ i ] ) {
				--rnd;			
				if ( 0 == rnd ) {
					// 状態を"オープンの状態"に変更
					statuses[ i ] = STATUS_OPEN;
					// カード番号を代入
					cardnum = cards[ i ];
					//記憶を登録
					memory[ i ] = cardnum;
					break;
				}
			}
		}

		// オープンしたカード番号を戻す
		return cardnum;
	}


	// 記憶したカード番号で隠されているカードをオープン
	private static boolean openMemoryCard( int cardnum )
	{
		for ( int i = 0; i < statuses.length; i++ ) {
			if ( STATUS_HIDE == statuses[ i ] ) {
				if ( cardnum == memory[ i ] ) {
					// 状態を"オープンの状態"に変更
					statuses[ i ] = STATUS_OPEN;
					return true;
				}
			}
		}

		return false;
	}


	// "オープン状態"の2枚のカード番号が同じかを判定	
	private static boolean isPair()
	{
		int number, cardnum;

		number = 0;
		cardnum = 0;
		for ( int i = 0; i < statuses.length; i++ ) {
			if ( STATUS_OPEN == statuses[ i ] ) {
				++ number;
				if ( 1 == number ) {
					// 1枚目
					cardnum = cards[ i ]; 
				}
				else {
					// 2枚目
					if ( cardnum == cards[ i ] ) {
						return true;
					}
					break;
				}
			}
		}

		return false;
	}


	// 状態の変更(旧状態→新状態)
	private static void replaceStatus( int oldStatus, int newStatus )
	{
		for ( int i = 0; i < statuses.length; i++ ) {
			if ( oldStatus == statuses[ i ] )
				statuses[ i ] = newStatus;
		}
	}
	

	// メイン
	public static void main( String[] args ) {
		// カードの初期化
		initCards();

		// 状態の初期化
		initStatuses();

		// 記憶の初期化
		initMemory();

		// 神経衰弱本体
		// 無限ループを作成(ループを抜ける条件をなし)
		for ( int turn = 1; ; ++ turn ) {
			// ターン番号の出力
			System.out.println( "ターン:" + turn );

			// カードを出力(オープン前の状態)
			outputCards();

			// カードをランダムに1枚オープン
			int cardnum1 = openCard();

			// 記憶しているカードがあればそのカードをオープン
			if ( !openMemoryCard( cardnum1 ) ) {
				// カードをランダムに1枚オープン
				int cardnum2 = openCard();
			}
			else {
				System.out.println( "記憶からカードをオープン!" );
			}

			// カードを出力(オープン後の状態)
			outputCards();

			// オープンしているカードがペアかどうか判定
			if ( isPair() )
				replaceStatus( STATUS_OPEN, STATUS_PAIR );
			else
				replaceStatus( STATUS_OPEN, STATUS_HIDE );

			// 全てペアになったらループを抜ける
			if ( 52 == getStatusNumber( STATUS_PAIR ) )
				break;
		}

		// カードの最終結果を出力
		System.out.println( "最終結果" );
		outputCards();
	}
}

コンパイル ソースコードが「ANSI」の場合

C:\talavax\javasample>javac -encoding sjis ShinkeiSuijaku.java

コンパイル ソースコードが「UTF-8」の場合

C:\talavax\javasample>javac ShinkeiSuijaku.java

実行

C:\talavax\javasample>java ShinkeiSuijaku

出力結果

ターン:1
*************
*************
*************
*************

*************
*5***********
*************
**2**********

ターン:2
*************
*************
*************
*************

*************
*5*********4*
*************
*************

     :

ターン:15
***2*K*7*****
*5**5******44
*4*7K*******4
**2**********

記憶からカードをオープン!
**32*K*7*****
*5**5****3*44
*4*7K*******4
**2**********

ターン:16
**32*K*7*****
*5**5****3*44
*4*7K*******4
**2**********

*132*K*7*****
*5**5****3*44
*4*7K*******4
**2*********9

     :

ターン:46
8132JKK7921AK
55*75Q1593344
24Q7K6JA6A634
812J*J6AQ7Q99

記憶からカードをオープン!
8132JKK7921AK
55875Q1593344
24Q7K6JA6A634
812J8J6AQ7Q99

最終結果
8132JKK7921AK
55875Q1593344
24Q7K6JA6A634
812J8J6AQ7Q99

以上です。

Javaソースコードの解説は、以下の記事を参照してください。

自動で神経衰弱を行うJavaのソースコードを紹介しています。興味のある方は、ご覧ください。

2021.03.31

自動で神経衰弱を行うJavaのソースコードを紹介しています。興味のある方は、ご覧ください。

2021.03.31

自動で神経衰弱を行うJavaのソースコードを紹介しています。興味のある方は、ご覧ください。

2021.03.31

自動で神経衰弱を行うJavaのソースコードを紹介しています。興味のある方は、ご覧ください。

2021.03.31

関連コンテンツ

トランプゲームの1つポーカーの役を判定をプログラムを作成してみませんか?。興味のある方は、ご覧ください。

2020.08.27

トランプ(カード)を扱うクラスを紹介しています。

2019.08.05

配列に格納されている数値をランダムに並び替える方法を詳しく解説しています。ソースコード付きです。

2016.01.31

式の値によって処理を分岐する方法を詳しく解説しています。

2016.08.04

変数やクラスに格納されている値をコンソール出力する方法は?

2020.03.23

乱数の意味と、Math.randomメソッドの使い方をソースコードを使って詳しく解説しています。

2015.12.27

1から6のサイコロの目が出る確率を割り出すプログラムの作りかたを解説しています。

2020.05.07

2つのサイコロを振って同じ目が出る確率を割り出すプログラムの作り方を解説しています。

2020.08.25

処理を繰り返すために使用するfor文について解説しています。

2020.03.23

条件式を判断して処理を分岐する方法を詳しく説明しています。

2023.03.20

メソッドを抜けるときに使用するreturn文について説明しています。

2020.03.20

プログラムの最初に実行されるメソッドは?

2022.12.13

プログラミングで使う変数って何?

2020.03.23

Javaのプログラムを書いてみませんか?プログラムの書き方をくわしく説明しています。

2020.03.23

「Javaソースコード」から実行可能な「オブジェクトコード」に変換する方法をくわしく説明しています。

2020.03.23

Javaのプログラムを作ってみませんか?プログラミングに必要なものの用意から実行までを説明しています。

2020.03.23

Javaの学習に役立つソースコードを多数紹介しています。是非、ご覧ください。

2022.09.10

Swingパッケージを使ってグラフィック表示を行う方法を解説しています。

2020.03.23

画像フォーマット形式・色・大きさ・傾きなどの変更、特定の図形(文字・記号など)を見つけたり、取り出したりする画像処理について詳しく解説。

2015.11.29

繰り返し処理を使ったJavaのソースコードサンプルを紹介しています。

2020.03.23

配列を使うJavaソースコードを多数紹介しています。

2021.05.18

数学に関係するJavaのメソッドやソースコードなどを紹介しています。

2022.10.25

三角形、台形、円などいろいろな図形の面積を計算するプログラムを紹介しています。詳しくは、記事をご覧ください。

2021.05.18

StringクラスとStringBuilderクラスを利用したプログラミングの仕方を紹介しています。

2016.12.16

Javaを使った簡単な応用プログラム(生年月日から年齢を計算プログラムなど)を紹介しています。

2022.07.07

プログラミング、ITに関する用語をまとめています。

2022.10.17

日本で使われてきた伝統文様「和柄」について解説しています。

2022.07.27

プログラミング言語とは?種類や特徴について説明しています。

2022.08.03

「ゆるゆるプログラム」のコンテンツを紹介しています。興味のある方はこの記事をご覧ください。

2020.03.23

広告