OCN光で最大124,800円おトク!

三目並べ

三目並べ(○×ゲーム)のプログラムにコンピュータとの対戦を付けたいのですがどうすればいいのでしょうか。教えてください。

ソースプログラム↓↓
http://ime.nu/codepad.org/wfwkEbVP


実行結果はこんな感じにしたいです。

1Pと2Pとの交互に対戦しますか?
1Pとコンピュータとの対戦にしますか?
プレイヤ同士の対戦なら1を、コンピュータとの対戦なら2を入力してください:

こんな感じで選らばせて対戦できるようにしてほしいです。

※1Pのマスは○でコンピュータのマスは×でお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

まず、


> 1Pと2Pとの交互に対戦しますか?
> 1Pとコンピュータとの対戦にしますか?
> プレイヤ同士の対戦なら1を、コンピュータとの対戦なら2を入力してください:

というのをだすのは、get_pos関数をマネして書いたらいいです。
あとは2Pの代わりにコンピューターに打たせればいいだけです。

コンピューターにどう打たせたいかは、評価関数を適当に作ってください、
http://ja.wikipedia.org/wiki/%E8%A9%95%E4%BE%A1% …

三目並べだと評価関数に全通り計算させれば絶対負けないコンピュータになってしまいますけどね。

この回答への補足

それっぽくは出来たのですが、殆ど乱数で決めてしまう感じになってしまいました。
http://codepad.org/2VItJ1Bt

どう打たせたいかプログラム上でどう書けばいいのかわかりません。

それと先手後手をジャンケンで決めれるようにしたいのですがどうすればよろしいでしょうか。

補足日時:2010/06/29 22:13
    • good
    • 0
この回答へのお礼

ありがとうございます。上手くいきました。

お礼日時:2011/03/30 00:27

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q[C言語]三目並べ

三目並べのプログラムで、以下のようなコンピュータの思考ルーチンを作っている所なのですが、
/* 後手で先手に初めに真ん中に置かれたら角に置く */
/* 後手で先手に初めに角に置かれたら真ん中に置く */
この二つがうまくいかないようで困っています。どこか間違っているのでしょうか?

void com( char te )
{
int total,kado,aite,a,tate,yoko,ok = 0;

/*
0 = 空 te = 1(○) → aite = 2(×)
1 = ○ te = 2(×) → aite = 1(○)
2 = ×
*/
/* 勝てる場所を探す */
for ( tate = 0; tate < 3; tate++ ) { /* 横一列 */
if( brd[tate][0] == 0 && brd[tate][1] == te && brd[tate][2] == te ) {
brd[tate][0] = te;
return;
}
if( brd[tate][0] == te && brd[tate][1] == 0 && brd[tate][2] == te ) {
brd[tate][1] = te;
return;
}
if( brd[tate][0] == te && brd[tate][1] == te && brd[tate][2] == 0 ) {
brd[tate][2] = te;
return;
}
}
for ( yoko = 0; yoko < 3; yoko++ ) { /* 縦一列 */
if( brd[0][yoko] == 0 && brd[1][yoko] == te && brd[2][yoko] == te ) {
brd[0][yoko] = te;
return;
}
if( brd[0][yoko] == te && brd[1][yoko] == 0 && brd[2][yoko] == te ) {
brd[1][yoko] = te;
return;
}
if( brd[0][yoko] == te && brd[1][yoko] == te && brd[2][yoko] == 0 ) {
brd[2][yoko] = te;
return;
}
}
if( brd[0][0] == 0 && brd[1][1] == te && brd[2][2] == te ) { /* 斜め1 */
brd[0][0] = te;
return;
}
if( brd[0][0] == te && brd[1][1] == 0 && brd[2][2] == te ) {
brd[1][1] = te;
return;
}
if( brd[0][0] == te && brd[1][1] == te && brd[2][2] == 0 ) {
brd[2][2] = te;
return;
}
if( brd[0][2] == 0 && brd[1][1] == te && brd[2][0] == te) { /* 斜め2 */
brd[0][2] = te;
return;
}
if( brd[0][2] == te && brd[1][1] == 0 && brd[2][0] == te) {
brd[1][1] = te;
return;
}
if( brd[0][2] == te && brd[1][1] == te && brd[2][0] == 0) {
brd[2][0] = te;
return;
}

/* 相手の勝ちを阻止する */

aite = te % 2 + 1;
for ( tate = 0; tate < 3; tate++ ) { /* 横一列 */
if( brd[tate][0] == 0 && brd[tate][1] == aite && brd[tate][2] == aite){
brd[tate][0] = te;
return;
}
if( brd[tate][0] == aite && brd[tate][1] == 0 && brd[tate][2] == aite){
brd[tate][1] = te;
return;
}
if( brd[tate][0] == aite && brd[tate][1] == aite && brd[tate][2] == 0){
brd[tate][2] = te;
return;
}
}
for ( yoko = 0; yoko < 3; yoko++ ) { /* 縦一列 */
if( brd[0][yoko] == 0 && brd[1][yoko] == aite && brd[2][yoko] == aite){
brd[0][yoko] = te;
return;
}
if( brd[0][yoko] == aite && brd[1][yoko] == 0 && brd[2][yoko] == aite){
brd[1][yoko] = te;
return;
}
if( brd[0][yoko] == aite && brd[1][yoko] == aite && brd[2][yoko] == 0){
brd[2][yoko] = te;
return;
}
}
if( brd[0][0] == 0 && brd[1][1] == aite && brd[2][2] == aite){ /* 斜め1 */
brd[0][0] = te;
return;
}
if( brd[0][0] == aite && brd[1][1] == 0 && brd[2][2] == aite ) {
brd[1][1] = te;
return;
}
if( brd[0][0] == aite && brd[1][1] == aite && brd[2][2] == 0 ) {
brd[2][2] = te;
return;
}
if( brd[0][2] == 0 && brd[1][1] == aite && brd[2][0] == aite){ /* 斜め2 */
brd[0][2] = te;
return;
}
if( brd[0][2] == aite && brd[1][1] == 0 && brd[2][0] == aite) {
brd[1][1] = te;
return;
}
if( brd[0][2] == aite && brd[1][1] == aite && brd[2][0] == 0) {
brd[2][0] = te;
return;
}

/* 後手で先手に初めに角に置かれたら真ん中に置く */
if ( te == 2 ) {
for ( a = 0; a < 9; a++ ) {
total += brd[a/3][a%3];
}
kado = brd[0][0] + brd[0][2] + brd[2][0] + brd[2][2];
if ( total == 1 && kado ==1){
brd[1][1] = te;
return;
}
}

/* 後手で先手に初めに真ん中に置かれたら角に置く */
if ( te == 2 ) {
for ( a = 0; a < 9; a++ ) {
total += brd[a/3][a%3];
}
if ( total == 1 && brd[1][1] == aite){
brd[0][0] = te;
return;
}
}


/* ランダム */
srandomdev();
do {
a = random() % 9;
tate = a/3;
yoko = a%3;
if ( brd[tate][yoko] == 0 ) {
ok = 1;
}
} while ( ok == 0 );

/* 盤面に書き込み */
brd[tate][yoko] = te;
}

三目並べのプログラムで、以下のようなコンピュータの思考ルーチンを作っている所なのですが、
/* 後手で先手に初めに真ん中に置かれたら角に置く */
/* 後手で先手に初めに角に置かれたら真ん中に置く */
この二つがうまくいかないようで困っています。どこか間違っているのでしょうか?

void com( char te )
{
int total,kado,aite,a,tate,yoko,ok = 0;

/*
0 = 空 te = 1(○) → aite = 2(×)
1 = ○ te = 2(×) → aite = 1(○)
2 = ×
*/
/* 勝てる場所を探す...続きを読む

Aベストアンサー

totalの初期値が設定されていないからでは?

QC言語で簡単なゲームを作る方法

僕はC言語を学び始めた程度ですが、一番簡単に作れるゲームとその作り方(ソース)を教えて下さい。お願いします。

Aベストアンサー

★じゃんけんゲームのソースです。

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

// じゃんけん定数
#define JKN_GOO  (0)
#define JKN_CHOKI (1)
#define JKN_PA  (2)

// 勝敗の定数
#define TYP_KATI (0)
#define TYP_MAKE (1)
#define TYP_AIKO (2)

// じゃんけんの判定関数
int check( int human, int computer )
{
 if ( human == computer ){
  return TYP_AIKO;
 }
 switch ( human ){
  case JKN_GOO:  return ((computer == JKN_CHOKI) ? TYP_KATI : TYP_MAKE);
  case JKN_CHOKI:  return ((computer == JKN_PA) ? TYP_KATI : TYP_MAKE);
  case JKN_PA:  return ((computer == JKN_GOO) ? TYP_KATI : TYP_MAKE);
  default:   return -1;
 }
}

// じゃんけんゲーム
int main( void )
{
 // ゲーム変数
 int count;  // 勝負回数
 int kati = 0; // 勝ちカウンタ
 int make = 0; // 負けカウンタ
 // 一時変数
 int human;  // キー入力の一時変数(人間用)
 int computer; // 乱数発生の一時変数(コンピュータ用)
 
 // (6)じゃんけん勝負を10回行う
 printf( "★じゃんけんゲーム(10回勝負)\n\n" );
 for ( count = 1 ; count <= 10 ; count++ ){
  // (1)人間:3つの状態を入力
  printf( "%2d回目…[1]グー [2]チョキ [3]パー を入力して下さい:", count );
  do {
   // (2)キー入力
   switch ( getche() ){
    case '1': human = JKN_GOO; break;
    case '2': human = JKN_CHOKI; break;
    case '3': human = JKN_PA; break;
    default: human = -1; break;
   }
  } while ( human == -1 );
  
  // (3)コンピュータ:3つの状態を乱数で決める
  computer = (rand() % 3);
  // (4)人間vsコンピュータの勝負
  switch ( check(human,computer) ){
   case TYP_KATI:
    kati++;
    printf( "⇒勝ち。\n" );
    break;
   case TYP_MAKE:
    make++;
    printf( "⇒負け。\n" );
    break;
   case TYP_AIKO:
    printf( "⇒引き分け。\n" );
    break;
   default:
    printf( "⇒エラー。\n" );
    break;
  }
 }
 // (7)結果表示
 printf( "\n★じゃんけんゲームの結果\n" );
 printf( "人間    :%d 回勝ち\n", kati );
 printf( "コンピュータ:%d 回勝ち\n", make );
 printf( "※引き分け回数は %d 回でした。\n", (10 - kati - make) );
 return 0;
}

注意:全角空白をタブ文字に変換して下さい。

★じゃんけんゲームのソースです。

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

// じゃんけん定数
#define JKN_GOO  (0)
#define JKN_CHOKI (1)
#define JKN_PA  (2)

// 勝敗の定数
#define TYP_KATI (0)
#define TYP_MAKE (1)
#define TYP_AIKO (2)

// じゃんけんの判定関数
int check( int human, int computer )
{
 if ( human == computer ){
  return TYP_AIKO;
 }
 switch ( human ){
  case JKN_GOO:  return ((computer == JKN_CHOKI) ? TYP...続きを読む

QEnterキーを押されたら次の処理に移るという事をしたい。

コンソールアプリケーション上で文字列を表示させた後、ユーザーがエンターキーを押したら次の文字列を表示するという仕様にしたいのですが、エンターキーだけ入力待ちにするっていうのはどのように書けばいいんでしょうか?

Aベストアンサー

#include <stdio.h>

int main(void)
{
char *str[] = {"abc", "def", "ghi", "jkl"};
int i;

for(i = 0; i < 4; i ++){
while(getchar() != '\n') ;
puts(str[i]);
}
return 0;
}

Q教えてください(丸罰ゲーム)

三目ゲーム(9マスの丸罰ゲーム)のプログラムを書いてコンピューターを相手に対戦したとき、コンピュータの勝率をできるだけあげるにはどうしたらいいんでしょうか??何か参考になることなんでも教えてください。ホームページなど教えてもらえれば光栄です。お願いします。

Aベストアンサー

No10です。斜めの判断に記述間違いがあったんでついでに少し書き足して関数にしました。

int tsuginote(int *a)
{
int i,j,tate,yoko,naname1=0,naname2=0,kari=99;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if(a[j][i]==0){
tate=a[(j+1)%3][i]*a[(j+2)%3][i];
yoko=a[j][(i+1)%3]*a[j][(i+2)%3];
if(i==j){
naname1=a[(j+1)%3][(i+1)%3]*a[(j+2)%3][(i+2)%3];
}
if(i+j==2){
naname2=a[(j+1)%3][(i+2)%3]*a[(j+2)%3][(i+1)%3];
}
if((tate==4)||(yoko==4)||(naname1==4)||(naname2==4)){
return 10*i+j;
}else if((tate==1)||(yoko==1)||(naname1==1)||(naname2==1)){
kari=10*i+j
}
}
}
}
return kari;
}

これで戻り値が99のときはランダムに、0-22の時はその指示通りにでどうでしょう。

No10です。斜めの判断に記述間違いがあったんでついでに少し書き足して関数にしました。

int tsuginote(int *a)
{
int i,j,tate,yoko,naname1=0,naname2=0,kari=99;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
if(a[j][i]==0){
tate=a[(j+1)%3][i]*a[(j+2)%3][i];
yoko=a[j][(i+1)%3]*a[j][(i+2)%3];
if(i==j){
naname1=a[(j+1)%3][(i+1)%3]*a[(j+2)%3][(i+2)%3];
}
if(i+j==2){
naname2=a[(j+1)%3][(i+2)%3]*a[(j+2)%3][(i+1)%3];
}
if((tate==4)||(yoko==4)||(naname1==4)||(naname2==4)){
return...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QC言語で五目並べを作成しているのですが…

学校のC言語の授業で5×5マスの五目並べを作っています。
教科書を見ながら、がんばっていましたが行き詰ってしまったので、ヒントを下さい。
基本的なことしか習っていないので、あまり高度なことはできません。

行き詰った点
・すでに置かれているマスには置けないようにすること。
・縦、横、斜めのどれか5マス揃うと、勝利と表示されてゲームが終 了すること。
・引き分けの表示の仕方

面倒とは思いますが、どうかよろしくお願いします。

↓CPPファイル
ttp://sugar310.dip.jp/cgi/upload/source/up21525.jpg
ttp://sugar310.dip.jp/cgi/upload/source/up21527.zip

Aベストアンサー

nokyonへ 
これあげる

#include<stdio.h>
int main(void){
static char a[6][6]={{' ','1','2','3','4','5'},
{'1',' ',' ',' ',' ',' '},
{'2',' ',' ',' ',' ',' '},
{'3',' ',' ',' ',' ',' '},
{'4',' ',' ',' ',' ',' '},
{'5',' ',' ',' ',' ',' '}};
int count=0,judge=0;
int i,j;

for(;;){
//盤の表示
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}
//先手
for(;;){
for(;;){
printf("行\n");
scanf("%d",&i);
if(i==0)
continue;
if(i<6)
break;
printf("置けません\n");
}
for(;;){
printf("列\n");
scanf("%d",&j);
if(j==0)
continue;
if(j<6)
break;
printf("置けません\n");
}
if(a[i][j]!=' '){
printf("置けません\n");
continue;}
else if(a[i][j]=' '){
a[i][j]='X';
count++;
break;
}
}

//先手終了
//縦判定
for(j=1;j<6;j++){
judge=0;
for(i=1;i<6;i++){
if(a[i][j]=='X')
judge++;
}
if(judge==5){
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}
printf("you win!!");
return 0;}
}
//横判定
for(j=1;j<6;j++){
judge=0;
for(i=1;i<6;i++){
if(a[j][i]=='X')
judge++;
}
if(judge==5){
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}
printf("you win!!");
return 0;}
}
//斜め(右下がり)判定
judge=0;{
for(j=1;j<6;j++){
if(a[j][j]=='X')
judge++;
}
if(judge==5){
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}
printf("you win!!");
return 0;}}
//斜め(右上がり)判定
judge=0;
for(i=1;i<6;i++){
if(a[i][6-i]=='X')
judge++;
}
if(judge==5){
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}
printf("you win!!");
return 0;}
if(count==25){
printf("引き分け");
}


//盤の表示
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}


//後手
for(;;){
for(;;){
printf("行\n");
scanf("%d",&i);
if(i==0)
continue;
if(i<6)
break;
printf("置けません\n");
}
for(;;){
printf("列\n");
scanf("%d",&j);
if(j==0)
continue;
if(j<6)
break;
printf("置けません\n");
}
if(a[i][j]!=' '){
printf("置けません\n");
continue;}
else if(a[i][j]=' '){
a[i][j]='O';
count++;
break;
}
}
//縦判定
for(j=1;j<6;j++){
judge=0;
for(i=1;i<6;i++){
if(a[i][j]=='O')
judge++;
}
if(judge==5){
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}
printf("you win!!");
return 0;}
}
//横判定
for(j=1;j<6;j++){
judge=0;
for(i=1;i<6;i++){
if(a[j][i]=='O')
judge++;
}
if(judge==5){
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}
printf("you win!!");
return 0;}
}
//斜め(右下がり)判定
judge=0;{
for(j=1;j<6;j++){
if(a[j][j]=='O')
judge++;
}
if(judge==5){
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}
printf("you win!!");
return 0;}}
//斜め(右上がり)判定
judge=0;
for(i=1;i<6;i++){
if(a[i][6-i]=='O')
judge++;
}
if(judge==5){
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
printf("\n");
}
printf("you win!!");
return 0;}
if(count==25){
printf("引き分け");
}

//判定群終了

}
return 0;
}

nokyonへ 
これあげる

#include<stdio.h>
int main(void){
static char a[6][6]={{' ','1','2','3','4','5'},
{'1',' ',' ',' ',' ',' '},
{'2',' ',' ',' ',' ',' '},
{'3',' ',' ',' ',' ',' '},
{'4',' ',' ',' ',' ',' '},
{'5',' ',' ',' ',' ',' '}};
int count=0,judge=0;
int i,j;

for(;;){
//盤の表示
for(i=0;i<6;i++){
for(j=0;j<6;j++){
printf("%c",a[i][j]);
}
...続きを読む

Q  miniMax法の説明がいまいちわからない

こんにちは。
Javaでゲームを制作していてminiMax法というゲームのAIの働きを説明しているサイトを調べているのですが、いまいち説明が理解できません。

ツリー木で最初に自分の手で最大評価値を選択し、相手の番になると最小評価値を選択する
そしてまた自分の手になると最大評価値を選択する。
こうやっていっても5手、6手深く読んでも仕方ないと思うのですがどうなんでしょうか?

サイトに載っているツリー木を見るとただ自分の手だと最大評価値になる手を選択すればいいだけ
なんじゃないでしょうか?3手、4手よむ必要はないんじゃないでしょうか?

Aベストアンサー

あ~, こういうことかなぁ....

「ツリーの一番上が6そこから下が順に評価値が4,8,9,10だったとすると」って書いてありますが, この 4 とか 8 とかの評価値を求めるためには一般に「深く読む」ことが必要なんです. つまり, 図2 を例にすると, 「丸の 2番」の局面の評価値を計算するためには (その下の) 「四角の 3番」や「四角の 6番」に対応する局面の評価値を求める必要があります (そしてそれらの評価値の最小値を「丸の 2番」の局面の評価値とする). もちろん, 「四角の 3番」の局面で評価値を求めるためにはさらにその下の「丸の 4番」や「丸の 5番」の局面の評価値が必要です (それらの評価値の最大値が「四角の 3番」の局面の評価値).

こうやって最終局面 (ゲームの木における葉) にたどりついたときに, ようやく「真の評価値」が決まります. ただし, よほど単純なゲームであったりよほど煮詰まった局面でもない限り, あまりにも時間がかかるので「最終局面まで読み進める」ことはできません. 従って, 通常あるところまで読み進めたところで打ち切って「経験に基づく評価値」を割り当てることになります. もちろん, この「経験に基づく評価値」が「真の評価値」と一致するとは保証されないので, 「こっちの方がいいと思ったんだけどそれは間違いだった」ということはあります. あなたの挙げた例で, 評価値 10 の局面に進めたあとで「そこからさらに8, 4, 1,と評価値があるとすると、そこから今度は最小値を選ぶわけだから1を選択します」というのがまさにこれ. 「1手だけ読むと評価値 10 の局面が (自分にとって) もっともうれしいんだけど, 実はそこから相手に絶妙手があって評価値が 1 にまで減ってしまう」ということです. 「ポカ」とか「勝手読み」, あるいは「わなにはまった」というやつですな.

いずれにしても, 「そもそも評価値を計算するためには深く読まなきゃならない」ということです.

あ~, こういうことかなぁ....

「ツリーの一番上が6そこから下が順に評価値が4,8,9,10だったとすると」って書いてありますが, この 4 とか 8 とかの評価値を求めるためには一般に「深く読む」ことが必要なんです. つまり, 図2 を例にすると, 「丸の 2番」の局面の評価値を計算するためには (その下の) 「四角の 3番」や「四角の 6番」に対応する局面の評価値を求める必要があります (そしてそれらの評価値の最小値を「丸の 2番」の局面の評価値とする). もちろん, 「四角の 3番」の局面で評価値を求めるためには...続きを読む

Qセグメンテーション違反

C言語を使用しています。

構造体に値をいれようとしたら、コンパイルは出来るのですが、実行時に
「セグメンテーション違反です (core dumped)」
となってしまい、それ以上行えません。

構造体と代入したい変数との型は、合っています。

いろいろ本などで見ましたが、何が原因かわからず困っています。
教えてください。
宜しくお願いします。

Aベストアンサー

OSは何でしょうか。コンパイラは何を使用していますか?
通常、デバッグオプションをつけて実行すると、異常の発生したソースの箇所で止まりますので、それが手がかりになります。またNo1の方が言われてますように、ソースが公開できるのであれば、ソースを提示するのが良いかと思います。

QJavaでゲーム

Javaで簡単な○×ゲームを作成しなければならないのですが,全く方法がわかりません.できればファイルの入出力を利用した方法を教えてください.もしくは,参考になるページを教えていただけませんか?

Aベストアンサー

Javaの知識はあるんですよね?何がわからないのですか?アルゴリズム?でしたら、マウスのクリック回数をカウントして、奇数ならマル、偶数ならバツにして、マウスの座標を検出し、あらかじめ用意しておいたintの二次元配列(int[3][3])にマルなら1,バツなら2を代入する、といったような方法を使えば勝敗の判定が楽にできるのではないでしょうか。

QC#で電卓のプログラムを組んでいるのですが

質問です。

電卓のプログラムにおいて、小数点のボタンがありますよね。それを重複して入力されないようにしたいのですが。何か良い方法はないでしょうか?

よろしくお願い致します。

Aベストアンサー

>if(s.Equals('.'))
>の部分で、コンパイルすると、));にしろとのエラーメッセージが出るのですが、なぜなんでしょうか?

多分、私の書いた部分をそのままコピペしているため
ifの前に全角の空白が入っているんだと思います。
(掲示板だとTabが無効になるので代わりに全角空白を使いました)


人気Q&Aランキング