上のプログラムのソースです。

//作成 2020/04/18, 2020/04/20
//プログラミングの考え方
//結果が2桁までの加算と減算を自動生成する

PFont myFont1; //フォントを格納する変数
String Calculation ="" ;
String Shiki ="";
String Kotae ="";
String Mojiretsu ="";

int Counter = 0 ;
String Key = "";
String CorrectWrong ="" ;
String Syutsudai = "";
String KeyIn = "";
int Wrong = 0;
int jikan = 0;
int fun = 0;
int byou = 0;
int start = 0;

void setup() {
  //キャンバスを設定。画面サイズ、背景色、色などを最初に設定します。
  size(1000, 600);
  //size([横幅], [縦幅])
  background(255);
  //background([0が黒〜255が白],[透明度]);

  myFont1 = createFont( "メイリオ", 30 );
  //createFont(name, size) フォントを動的に作成する
  //http://zawaworks.hatenablog.com/entry/2017/03/13/160055
  //"MS ゴシック" "MS 明朝"
  textFont( myFont1 );
  //textFont() 使用フォントを選択する。loadFont()やcreateFont()で作成したフォントを使えるようにします。
}


void mousePressed() {
  //●mousePressed() 関数で、マウスボタンが押されたイベントを捕まえる
  //マウスボタンを押したタイミングをタイムリーに検知したいなら、mousePressed()関数でボタンが押されたタイミングで処理を行う。
  //●mouseClicked() 関数で、マウスボタンが押されて離された事を捕まえる
  //「ボタンが、押されて離されたタイミング」で呼び出される事です。カチッとクリックしたタイミングで処理を行うための関数。

  //マウスの位置情報を取得 mouseX,mouseY
  //画面の右側をテンキーにする。

  if (mouseX>=320 && mouseX<440 && mouseY>=100 && mouseY<220) {
    Key = "7" ;
  } else if (mouseX>=440 && mouseX<560 && mouseY>=100 && mouseY<220) {
    Key = "8" ;
  } else if (mouseX>=560 && mouseX<=960 && mouseY>=100 && mouseY<220) {
    Key = "9" ;
  } else if (mouseX>=320 && mouseX<440 && mouseY>=220 && mouseY<340) {
    Key = "4" ;
  } else if (mouseX>=440 && mouseX<560 && mouseY>=220 && mouseY<340) {
    Key = "5" ;
  } else if (mouseX>=560 && mouseX<=960 && mouseY>=220 && mouseY<340) {
    Key = "6" ;
  } else if (mouseX>=320 && mouseX<440 && mouseY>=340 && mouseY<460) {
    Key = "1" ;
  } else if (mouseX>=440 && mouseX<560 && mouseY>=340 && mouseY<460) {
    Key = "2" ;
  } else if (mouseX>=560 && mouseX<=960 && mouseY>=340 && mouseY<460) {
    Key = "3" ;
  } else if (mouseX>=320 && mouseX<=960 && mouseY>=460 && mouseY<=580) {
    Key = "0" ;
  }

  //右下のキー入力状況表示を消す
  fill(255);
  noStroke();
  rect(620, 460, 90, 140);
  //rect(基準のx座標, 基準のy座標, 横幅, 縦幅)
  fill( 60 );

  if (mousePressed == true) {
    text( "true", 630, 500 );
  } else {
    text( "false", 630, 500 );
  }
  text( "Key " + Key, 620, 550 );
  //text(文字列, x座標, y座標)

  //リセット
  if (mouseX>0 && mouseX<1000 && mouseY>0 && mouseY<100) {
    loop();  
    fill(255);
    noStroke();
    rect(0, 0, 1000, 600);
    //rect(基準のx座標, 基準のy座標, 横幅, 縦幅)
    fill( 60 );
    Counter = 0 ;
    Wrong = 0;
    Syutsudai ="";
    start = millis()/1000;
  }
}


void mouseClicked () {
  //void mouseClicked() {
  //クリックすると、ここの処理が実行される

  //右下の状況表示を消す
  fill(255);
  noStroke();
  rect(620, 460, 90, 140);
  //rect(基準のx座標, 基準のy座標, 横幅, 縦幅)
  fill( 60 );

  //リセット
  if (mouseX>0 && mouseX<1000 && mouseY>0 && mouseY<100) {
    loop();  
    fill(255);
    noStroke();
    rect(0, 0, 1000, 600);
    //rect(基準のx座標, 基準のy座標, 横幅, 縦幅)
    fill( 60 );
    Counter = 0 ;
    Wrong = 0;
    Syutsudai ="";
    start = millis()/1000;
  }
}

void Coloring (String Key, String CorW ) {
  //テンキーを着色する。

  print("Key ");
  println(Key);  //デバッグ用にコンソールに出力
  print("CorW ");
  println(CorW);  //デバッグ用にコンソールに出力

  if (CorW == "Correct" || CorW == "Pending") { 
    fill( 0, 255, 0, 255 );
    switch(Key) {
    case "7":
      rect(320, 100, 120, 120);
      break;   //各 case 文ごとに break 文を最後に書く必要があります。
      //break 文を書かないと、処理は、合致した行以降の case 内の処理まで次々と実行されてしまいます
    case "8":
      rect(440, 100, 120, 120);
      break;
    case "9":
      rect(560, 100, 120, 120);
      break;
    case "4":
      rect(320, 220, 120, 120);
      break;
    case "5":
      rect(440, 220, 120, 120);
      break;
    case "6":
      rect(560, 220, 120, 120);
      break;
    case "1":
      rect(320, 340, 120, 120);
      break;
    case "2":
      rect(440, 340, 120, 120);
      break;
    case "3":
      rect(560, 340, 120, 120);
      break;
    case "0":
      rect(320, 460, 300, 120);
      break;
    }
    fill( 0, 255, 0, 255);
  }
  if (CorW == "Wrong") { 
    fill( 255, 0, 0, 255 );
    switch(Key) {
    case "7":
      rect(320, 100, 120, 120);
      break;   //各 case 文ごとに break 文を最後に書く必要があります。
      //break 文を書かないと、処理は、合致した行以降の case 内の処理まで次々と実行されてしまいます
    case "8":
      rect(440, 100, 120, 120);
      break;
    case "9":
      rect(560, 100, 120, 120);
      break;
    case "4":
      rect(320, 220, 120, 120);
      break;
    case "5":
      rect(440, 220, 120, 120);
      break;
    case "6":
      rect(560, 220, 120, 120);
      break;
    case "1":
      rect(320, 340, 120, 120);
      break;
    case "2":
      rect(440, 340, 120, 120);
      break;
    case "3":
      rect(560, 340, 120, 120);
      break;
    case "0":
      rect(320, 460, 300, 120);
      break;
    }
    fill( 255, 0, 0, 255);
  }
}


void draw() {

  fill( 128, 0, 255 );

  if (Counter >= 20) {
    fill(255);
    noStroke();
    rect(0, 0, 1000, 100);
    fill( 60 );
    text( "正解数 = " + str(20-Wrong) + " 、誤答数 = " + str(Wrong) + " でした。回答時間は " + str(int(fun)) + " 分 " + str(byou) + " 秒です。", 45, 30 );
    text( "このタイトル部分をクリックすると、再挑戦できます。", 45, 70 );
    //右下の状況表示を消す
    fill(255);
    noStroke();
    rect(620, 460, 90, 140);
    //rect(基準のx座標, 基準のy座標, 横幅, 縦幅)
    fill( 60 );
    noLoop();
  } else {
    text( "2桁までの足し算と引き算を、交互に、計20問生成します。", 45, 30 );
    //text(文字列, x座標, y座標)
    text( "中央のテンキーをマウスでクリックして回答して下さい。", 45, 70 );
  }

  //右側のテンキーを描く。
  //枠
  stroke(255);
  fill(200, 100);
  //fill() 塗りに色を付ける
  //fill(d) グレースケール。整数dが0なら黒、255なら白、その間の数は数が小さいほど濃い灰色。
  //fill(d,a) グレースケールだが、「透明度」を追加指定する。aの0は完全に透明、255は完全に不透明。
  rect(320, 100, 120, 120);
  //rect(基準のx座標, 基準のy座標, 横幅, 縦幅)
  rect(440, 100, 120, 120);
  rect(560, 100, 120, 120);
  rect(320, 220, 120, 120);
  rect(440, 220, 120, 120);
  rect(560, 220, 120, 120);
  rect(320, 340, 120, 120);
  rect(440, 340, 120, 120);
  rect(560, 340, 120, 120);
  rect(320, 460, 300, 120);
  //数
  fill( 0 );
  text("7", 370, 180 );
  text("8", 490, 180 );
  text("9", 610, 180 );
  text("4", 370, 300 );
  text("5", 490, 300 );
  text("6", 610, 300 );
  text("1", 370, 420 );
  text("2", 490, 420 );
  text("3", 610, 420 );
  text("0", 470, 540 );

  // 計算式を順次表示する
  //文字を取り出すには
  //http://mslabo.sakura.ne.jp/WordPress/make/processing%E3%80%80%E9
%80%86%E5%BC%95%E3%81%8D%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/%E6%96%87
%E5%AD%97%E3%82%92%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%99%E3%81%AB%E3%81%AF/
//http://maicommon.ciao.jp/ss/processing_g/string/ if (Counter % 2 == 0) { Calculation = "Add"; } else { Calculation = "Subt"; } //式を表示 if (Syutsudai =="") { if (Counter <10 ) { Mojiretsu = Keisann(Calculation); Shiki = Mojiretsu.substring(0, 10); text(Shiki, 20, 130 + 50*Counter ); Kotae = trim(Mojiretsu.substring(11)); } else if (Counter <20 ) { Mojiretsu = Keisann(Calculation); Shiki = Mojiretsu.substring(0, 10); text(Shiki, 710, 130 + 50*(Counter - 10) ); Kotae = trim(Mojiretsu.substring(11)); } Syutsudai = "sumi"; } if (Key != "") { print("Kotae0 "); println(Kotae); print("Key0 "); println(Key); print("Kotae.length() "); println(Kotae.length()); //デバッグ用にコンソールに出力 if (Kotae.length() == 2) { if (CorrectWrong == "Pending") { if (int(Kotae.substring(1, 2)) == int(Key)) { CorrectWrong ="Correct"; } else { CorrectWrong ="Wrong"; } KeyIn = KeyIn + Key; } else if (int(Kotae.substring(0, 1)) == int(Key)) { CorrectWrong ="Pending"; KeyIn = Key; } else { CorrectWrong ="Wrong"; KeyIn = Key; } Coloring (Key, CorrectWrong ) ; Key = ""; } if (Kotae.length()== 1) { if (int(Kotae) == int(Key)) { CorrectWrong ="Correct"; fill( 0, 100, 0 ); } else { CorrectWrong ="Wrong"; fill( 255, 50, 50 ); KeyIn = Key; } Coloring (Key, CorrectWrong ) ; Key = ""; } } //回答を表示 if (CorrectWrong =="Wrong" || CorrectWrong =="Correct") { if (Counter <10 ) { text(Kotae, 190, 130 + 50*Counter ); if (CorrectWrong =="Wrong") { fill(0); text(KeyIn, 250, 130 + 50*Counter ); Wrong = Wrong + 1; KeyIn = ""; } } else { text(Kotae, 880, 130 + 50*(Counter-10)); if (CorrectWrong =="Wrong") { fill(0); text(KeyIn, 940, 130 + 50*(Counter-10)); Wrong = Wrong + 1; KeyIn = ""; } } Counter = Counter + 1; Syutsudai = ""; CorrectWrong =""; jikan = millis()/1000 - start; fun = jikan/60; byou = jikan - fun*60; } } String Keisann(String AorS ) { String mojiretsu=""; int A; int B; int S; //ループ方法 //http://www.cho-design-lab.com/2013/05/29/processing-repeat/ //while(条件){繰り返す処理;繰り返す処理;…繰り返す処理;} //do {繰り返す処理;繰り返す処理;…繰り返す処理;} while(条件); //do ? whileは「条件の判定をする前に、一度繰り返し処理を行う」という繰り返し処理です。 //for(カウンタ初期化; 条件; カウンタ更新)繰り返す処理; do { A = int(random(99))+1; //random(2) は 0以上 2未満の数を発生する。命令intはこれの小数部分を切り捨てて整数化する。 //int(random(2)) は0または1になる。 B = int(random(99))+1; S = A+B; //} while (S >= 10); //デバッグ用に1桁で出題 } while (S >= 100); if (AorS == "Add") { mojiretsu = nf(A) + " + " + nf(B) + " = " + nf(S); } else if (AorS == "Subt") { mojiretsu = nf(S) + " - " + nf(A) + " = "+nf(B); } return mojiretsu; }

ホームページのトップに戻る