C言語でテトリスを作っています。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
makaron
記事: 3
登録日時: 12年前

C言語でテトリスを作っています。

#1

投稿記事 by makaron » 12年前

先ほど同じような投稿をしたのですが
ミスが多かったのでもう一度投稿します
すみません

テトリスをC言語で作っているのですが
その際コンパイラとしてCygwin、テキストエディタとしてEmacsを使っています

まだC言語歴がかなり浅く初心者です。
よろしくお願いします。

まず僕が思い描いているテトリスの要素というか実現したいことを箇条書きします
①フィールドを作る
フィールドは20×10マスでそのまわりに[]という壁を作成して
その上に番号を割り振っています
僕のソースは

コード:

#include <stdio.h>

void init(char A[22][12]){
  //壁を1、フィールドを0とする。
  int i,j;
  int EMPTY = 0;
  int WALL = 1;


  for(i=0;i<22;i++){
    for(j=0;j<12;j++){
      if((i == 0)||(i == 21)||(j == 0)||(j == 11)){
        A[i][j] = WALL;
      }else{
      A[i][j] = EMPTY;
    }
  }
}
}

void showGameField(char A[22][12]){
  //壁を[]、フィールドを として表示する。
  int k,i,j;

  for(k=0;k<11;k++){
    if(k){
      printf("%2d", k);
    }else{
      printf(" ");
        }
  }

  for(i=0;i<22;i++){
    printf("\n");
    for(j=0;j<12;j++){
     if(A[i][j] == 1){
        printf("[]");
      }else{
        printf(" ");
      }
    }
  }
}

int main(){
  char A[22][12];

  init(A);
  showGameField(A);

  return 0;
}
これはできました。
②7種類のテトリスのブロックを作成する
4×4のブロックフィールドにブロックの部分は2、ブロック以外のところは0として
2の部分には7種類の色を付けたいのですが
Cygwinではどうも白、マゼンタ、シアン、青、黒、黄、緑、赤の8種類しかないみたいなので
壁の[]を白で背景は黒、フィールドは で背景も文字色も黒、ブロックは黒以外の7色を使いたいと思います。
その際ブロックがある部分は■として色付けしてしまうと
ブロックが■
      ■
となりくっついてる感じがなくなってしまいます
これを解消するために
ブロックの部分は で文字色を7種類に変えればうまいこといくんじゃないかと仮説をたてたのですが
そのブロックを作って表示する方法がわからないです。
どのようにすればいいんでしょうか?
今この段階です。

コード:

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

void createBlock(void){
//7種類のブロックの作成
int i,j;
char Block[i][j];

for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
Block[i][j]=0;
}
}


switch(rand() % 7){
case 0:
Block[1][1]=1; Block[2][1]=1; Block[1][2]=1; Block[2][2]=1;
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
if(Block[i][j]){
printf("■");
}else{
printf(" ");
}
}
printf("\n");
}
return;
case 1:
Block[1][0]=1; Block[1][1]=1; Block[1][2]=1; Block[1][3]=1;
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
if(Block[i][j])
printf("■");
}else{
printf(" ");
}
}
printf("\n");
}
return;
case 2:
Block[1][1]=1; Block[1][2]=1; Block[2][2]=1; Block[1][3]=1;
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
if(Block[i][j])
printf("■");
}else{
printf(" ");
}
}
printf("\n");
}
return;
case 3:
Block[1][1]=1; Block[2][1]=1; Block[1][2]=1; Block[1][3]=1;
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
if(Block[i][j])
printf("■")
}else{
printf(" ");
}
}
printf("\n");
}
return;
case 4:
Block[1][1]=1; Block[2][1]=1; Block[2][2]=1; Block[2][3]=1;
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
if(Block[i][j])
printf("■");
}else{
printf(" ");
}
}
printf("\n");
}
return;
case 5:
Block[2][1]=1; Block[1][2]=1; Block[2][2]=1; Block[1][3]=1;
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
if(Block[i][j])
printf("■");;
}else{
printf(" ");
}
}
printf("\n");
}
return;
case 6:
Block[1][1]=1; Block[1][2]=1; Block[2][2]=1; Block[2][3]=1;
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
if(Block[i][j])
printf("■");
}else{
printf(" ");
}
}
printf("\n");
}
return;
}
}

int main(){
int i,j;
char Block[i][j];

srand((unsigned int)time(NULL));
for(i=0;i<10;i++){
printf("%c", createBlock());
}


return 0;
}
まずどこが間違っているのでしょうか?
案としてはランダムの数を7で割った余りで
そのあまりが0なら正方形のブロック、
1なら横棒のブロックが生成されるというブロックを作っているつもりなのですが
間違っているでしょうか?
これを表示することもできません。

③ブロックをフィールドで移動させる
まずブロックフィールド4×4の左上の部分がフィールドのi=1,j=4の部分から落ちるように設定し
そのままキーボードのカーソル右を押すとブロックが右に
左を押すとブロックが左に
上を押すと回転
下を押すと落下といった風にしたいのですがどうしたらいいのでしょうか?
また下までブロックが落ちると次のブロックがまたランダムで選ばれて下りてくるようにするにはどうしたらいいでしょうか?

④衝突判定
ブロックが回転しようとしたときに
横の壁にあたったり
落下しているときや移動しているときに下の壁やすでに存在するブロックと衝突したときにエラーがでるように設定するにはどうしたらいいんでしょうか?
たぶん壁を1、ブロックも1、フィールドを0、ブロックフィールドのブロックがない部分は0という風にしているので
1が重なるときはその操作を無効にするといった方法がただしいんでしょうか?

どのようにソースを書けばいいのでしょうか?

⑤ゲームオーバー処理
一番上まできても動けなくなった時にゲームオーバーになって
CONTINUE?[Y/N]と聞き
Yならばもう一度はじめから
Nならばプログラミングを終了といった風に設定したいです
どのようにすればいいでしょうか?

全然わからないことだらけで申し訳ないですが
ちょっとでもいいので力を貸していただけませんか?
よろしくお願いします。

返信まってます

non
記事: 1097
登録日時: 14年前

Re: C言語でテトリスを作っています。

#2

投稿記事 by non » 12年前

いたるところに文法エラーがあります。

それはおいといて、Cygwin上で作らなければいけないのですか?
Cygwinを動かしていると言うことは、Windowsなんでしょ?DxLibを使ってはいけないのですか?
non

アバター
バグ
記事: 130
登録日時: 15年前
住所: 愛媛県
連絡を取る:

Re: C言語でテトリスを作っています。

#3

投稿記事 by バグ » 12年前

non さんが書きました:いたるところに文法エラーがあります。

それはおいといて、Cygwin上で作らなければいけないのですか?
Cygwinを動かしていると言うことは、Windowsなんでしょ?DxLibを使ってはいけないのですか?
開発環境については別に何を使おうが自由なのでは?
コンソールアプリでも全然問題ないと思いますが・・・。

non
記事: 1097
登録日時: 14年前

Re: C言語でテトリスを作っています。

#4

投稿記事 by non » 12年前

バグ さんが書きました: 開発環境については別に何を使おうが自由なのでは?
コンソールアプリでも全然問題ないと思いますが・・・。
もちろん、そうです。ただ、テトリスの完成イメージを考えた場合、コンソールでは却って面倒にならないかなと考えました。
早めに、選択肢を提示しただけです。
non

non
記事: 1097
登録日時: 14年前

Re: C言語でテトリスを作っています。

#5

投稿記事 by non » 12年前

118行 printf("%c", createBlock());

createBlock() は値を返さない関数で作ろうとしてますから、
ここは、printfは使わずに
creatBlock();
だけにしましょう。

8行と114行 char Block[j];
iやjに値が入っていないので、これではまずいです。

後は、括弧やセミコロンが多数。
non

makaron
記事: 3
登録日時: 12年前

Re: C言語でテトリスを作っています。

#6

投稿記事 by makaron » 12年前

non さんが書きました:118行 printf("%c", createBlock());

createBlock() は値を返さない関数で作ろうとしてますから、
ここは、printfは使わずに
creatBlock();
だけにしましょう。

8行と114行 char Block[j];
iやjに値が入っていないので、これではまずいです。

後は、括弧やセミコロンが多数。


返信ありがとうございます
確かにcreateBlockはブロックを作ることだけを考えているので
printfはよくないですね

コード:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
void createBlock(void){
//7種類のブロックの作成
int i,j;
char Block[4][4];
 
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
Block[i][j]=0;
}
}
 
 
switch(rand() % 7){
case 0:
Block[1][1]=1; Block[2][1]=1; Block[1][2]=1; Block[2][2]=1;
return;

case 1:
Block[1][0]=1; Block[1][1]=1; Block[1][2]=1; Block[1][3]=1;
return;

case 2:
Block[1][1]=1; Block[1][2]=1; Block[2][2]=1; Block[1][3]=1;
return;

case 3:
Block[1][1]=1; Block[2][1]=1; Block[1][2]=1; Block[1][3]=1;
return;

case 4:
Block[1][1]=1; Block[2][1]=1; Block[2][2]=1; Block[2][3]=1;
return;

case 5:
Block[2][1]=1; Block[1][2]=1; Block[2][2]=1; Block[1][3]=1;
return;

case 6:
Block[1][1]=1; Block[1][2]=1; Block[2][2]=1; Block[2][3]=1;
return;
}
}
 
int main(){
int i,j;
char Block[4][4];
 
srand((unsigned int)time(NULL));
for(i=0;i<10;i++){
printf("%c", createBlock());
}
 
 
return 0;
}
でとりあえずは言われたことを直しましたが
ここからどうすれば出力ができるんですか?

あとswich文ではbreak;とするんではないんですか?
return;との違いがわかりません。

makaron
記事: 3
登録日時: 12年前

Re: C言語でテトリスを作っています。

#7

投稿記事 by makaron » 12年前

バグ さんが書きました:
non さんが書きました:いたるところに文法エラーがあります。

それはおいといて、Cygwin上で作らなければいけないのですか?
Cygwinを動かしていると言うことは、Windowsなんでしょ?DxLibを使ってはいけないのですか?
開発環境については別に何を使おうが自由なのでは?
コンソールアプリでも全然問題ないと思いますが・・・。

申し訳ないのですがCygwinではテトリスを作るうえでやめたほうがいいという意見はほかの質問コーナーでも言われました

ただCygwinで作れというのが今回の課題です。
そこはかえれないみたいです。

non
記事: 1097
登録日時: 14年前

Re: C言語でテトリスを作っています。

#8

投稿記事 by non » 12年前

makaron さんが書きました:
バグ さんが書きました: 申し訳ないのですがCygwinではテトリスを作るうえでやめたほうがいいという意見はほかの質問コーナーでも言われました

ただCygwinで作れというのが今回の課題です。
そこはかえれないみたいです。
課題ならしょうがないですね。
プログラムを見ましたが、まだ基本的な勉強がかなり足りません。なんでも良いから作れという課題なのでしょうか?
テトリスならかなり勉強しないと無理だと思います。

プログラムでは、char Block[4][4];が、2つの関数にあり、それぞれローカル変数なので名前は同じでも別の変数だということが
理解されていないようです。

とりあえず、動くようには直しました。

コード:

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

void createBlock(char Block[4][4]){
	//7種類のブロックの作成
	int i,j;
	//char Block[4][4];

	for(i=0;i<4;i++) {
		for(j=0;j<4;j++) {
			Block[i][j]=0;
		}
	}


	switch(rand() % 7){
case 0:
	Block[1][1]=1; Block[2][1]=1; Block[1][2]=1; Block[2][2]=1;
	return;

case 1:
	Block[1][0]=1; Block[1][1]=1; Block[1][2]=1; Block[1][3]=1;
	return;

case 2:
	Block[1][1]=1; Block[1][2]=1; Block[2][2]=1; Block[1][3]=1;
	return;

case 3:
	Block[1][1]=1; Block[2][1]=1; Block[1][2]=1; Block[1][3]=1;
	return;

case 4:
	Block[1][1]=1; Block[2][1]=1; Block[2][2]=1; Block[2][3]=1;
	return;

case 5:
	Block[2][1]=1; Block[1][2]=1; Block[2][2]=1; Block[1][3]=1;
	return;

case 6:
	Block[1][1]=1; Block[1][2]=1; Block[2][2]=1; Block[2][3]=1;
	return;
	}
}

void dispBlock(char Block[][4])
{
	int i,j;
	for(i=0;i<4;i++) {
		for(j=0;j<4;j++) {
			if(Block[i][j]){
				printf("■");
			}else{
				printf(" ");
			}
		}
		printf("\n");
	}
}



int main(){
	int i,j;
	char Block[4][4];

	srand((unsigned int)time(NULL));

	for(i=0;i<10;i++){
		createBlock(Block);
		dispBlock(Block);
	}


	return 0;
}
non

アバター
バグ
記事: 130
登録日時: 15年前
住所: 愛媛県
連絡を取る:

Re: C言語でテトリスを作っています。

#9

投稿記事 by バグ » 12年前

C言語の標準ライブラリ以外で使用してもいいものはありますか?
コンソールアプリで作るとしても、ゲームとして形にしたいのであれば・・・

1:任意の位置へ文字を表示する為にカーソル制御が必要ですが、そういう処理はどうする予定ですか?
2:外部からの入力(キーボードかな?)の受け取りはどうする予定ですか?

おそらく、この辺りがハッキリしないと難しいんじゃないかなぁ・・・と。
Windows.hとかconio.hが使用できるなら助言できるんですけど、おそらく使えないでしょうし・・・。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: C言語でテトリスを作っています。

#10

投稿記事 by ISLe » 12年前

Cygwinなら(n)cursesライブラリを使うのが王道ですかね。

テトリスはないですが、cursesライブラリの使い方はこちらを参考にしてください。
ISLeのビデオゲーム工房: curses

non
記事: 1097
登録日時: 14年前

Re: C言語でテトリスを作っています。

#11

投稿記事 by non » 12年前

任意の位置への移動はエスケープシーケンスが使えたのではないかと思います。
問題はキーの読み込みですね。検索したら
kbhitを作ったのがありました。
http://hatenaclang.blogspot.jp/2011/03/kbhit.html
動作、未確認ですがあしからず。(私のパソコンにはCygwinを入れてないので。)
non

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: C言語でテトリスを作っています。

#12

投稿記事 by softya(ソフト屋) » 12年前

cygwinでエスケープシーケンスで操作可能な事は以下の通りです。
「エスケープシーケンス」
http://7ujm.net/etc/esc.html
ただ、ISLeさんの紹介しているライブラリ使ったほうが分かりやすいですけどね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る