Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Tic-Tac-Toe (Felder)

Schreiben Sie eine Subroutine, die eine 3x3-Matrix (Spielfeld) entgegennimmt und prüft, ob es sich dabei um eine Siegesposition im Tic-Tac-Toe-Spiel handelt. Die Matrix besteht aus neun ganzen Zahlen (integer), und die Werte sind Null (0), sofern an der entsprechenden Stelle noch kein Zug getätigt wurde. Steht jedoch an einer Stelle eine Eins (1) oder eine Zwei (2), so entspricht dies der Spielernummer. Die Funktion soll genau dann true zurückgeben, wenn ein Spieler in einer horizontalen, vertikalen oder diagonalen Reihe alle drei Felder mit seiner Nummer besetzt hat. Prototyp:

siegesPosition(ticTacToe: integer[][]) : boolean

 

1 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

Kommentare (1)

wwbaselmemes 10. April 2018 14:49   reply report
abcdefghijklmnopqrstuvwxyz juhee

6 Lösung(en)

def tictactoe(m):

    # Reihen testen
    for i in range (3):
        z = 0
        faktor = 1
        for j  in range (3):
            z = z+ m[i][j]*faktor
            faktor = faktor * 3
        if z == 13 or z == 26:
            return True

    # Spalten testen
    for i in range (3):
        z = 0
        faktor = 1
        for j  in range (3):
            z = z+ m[j][i]*faktor
            faktor = faktor * 3
        if z == 13 or z == 26:
            return True

    # Diagonale testen
    if m[0][0] == 1 and m[1][1] == 1 and m[2][2] ==1 or m[0][0] == 2 and m[1][1] == 2 and m[2][2] ==2:
         return True
    if m[0][2] == 1 and m[1][1] == 1 and m[2][0] ==1 or m[0][2] == 2 and m[1][1] == 2 and m[2][0] ==2:
         return True

    # sonst       
    return False


spielstand1 = [
              [0,1,0],
              [1,0,1],
              [2,0,2]]

spielstand2 = [
              [1,2,0],
              [0,1,2],
              [0,0,1]]

spielstand3 = [
              [1,1,2],
              [0,2,1],
              [2,0,0]]

spielstand4 = [
              [0,0,2],
              [1,1,1],
              [0,2,0]]

spielstand5 = [
              [0,2,1],
              [0,2,1],
              [1,2,0]]

spielstand6 = [
              [0,2,1],
              [0,2,1],
              [0,0,1]]


print 'Spiel 1'
print tictactoe(spielstand1)
print 'Spiel 2'
print tictactoe(spielstand2)
print 'Spiel 3'
print tictactoe(spielstand3)
print 'Spiel 4'
print tictactoe(spielstand4)
print 'Spiel 5'
print tictactoe(spielstand5)
print 'Spiel 6'
print tictactoe(spielstand6)

                
/**
 * Prüfe, ob eine Matrix eine "Siegesposition" im Spiel
 * TicTacToe ist. 
 * Eine Siegesposition ist dann gegeben, wenn ein Spieler
 * (spieler 1 oder 2) eine Zeile, Spalte oder Diagonale 
 * mit drei seiner Steine belegen kann.
 * @author Philipp Gressly (phi AT gressly DOT ch) im    Nov. 2010
 */

public class TicTacToe {
  public static void main(String[] args) {
    new TicTacToe().top();
  }
  
  int [][][] alleSiegesReihen =
  {
    // Zeilen
    {{0, 0}, {0, 1}, {0, 2}},
    {{1, 0}, {1, 1}, {1, 2}},
    {{2, 0}, {2, 1}, {2, 2}},
    // Spalten
    {{0, 0}, {1, 0}, {2, 0}},
    {{0, 1}, {1, 1}, {2, 1}},
    {{0, 2}, {1, 2}, {2, 2}},
    // Diagonalen
    {{0, 0}, {1, 1}, {2, 2}},
    {{2, 0}, {1, 1}, {0, 2}}
  };
  
  // Position, zum Prüfen der Funktion "istSiegesPosition()"
  int[][] test = {
    {1, 0, 1},
    {2, 2, 1},
    {1, 0, 0}           
  };
  
  void top() {
     if(istSiegesPosition(test)) {
         System.out.println("test ist Siegesposition");
     }
  }

  // true, wenn die position eine SiegesPosition im TicTacToe ist.
  boolean istSiegesPosition(int[][] position) {
    for(int[][] siegesReihe : alleSiegesReihen) {
        if(istSiegesReihe(position, siegesReihe)) {
           return true;
       }
    }
    return false;
  }

  /**
   * Die SiegesReihe enthält drei Koordinaten im Tic-Tac-Toe
   * Feld.
   * @param position ist die fragliche Spielposition
   * @param siegesReihe ist eine 2x3-Matrix mit drei
   *        (spalten/zeilen) Koordinaten. Zum Beispiel {{0,0}, {1,1}, {2,2}}
   * @return wahr, wenn im TicTacToe (position) an den drei
   *         Positionen der "siegesReihe" der selbe Spieler
   *         steht (Dieser darf natürlich nicht Null (0) sein, denn
   *         dies bedeutet ein leeres Feld).
   */
  boolean istSiegesReihe(int[][] position, int[][] siegesReihe) {
    int spieler1 = spielerNr(position, siegesReihe, 0);
    // Spieler 0 == leeres Feld -> Der Spieler 0 kann nicht gewinnen
    if(0 == spieler1) {
        return false;
    }
    int spieler2 = spielerNr(position, siegesReihe, 1);
    int spieler3 = spielerNr(position, siegesReihe, 2);
    // Alle Positionen der Siegesreihe sind vom gleichen
    // Spieler belegt:
    return spieler1 == spieler2 && spieler1 == spieler3;
  }
 
  int spielerNr(int[][] position, 
                int[][] siegesReihe, 
                int positionInSiegesReihe) {
    int zeile  = siegesReihe[positionInSiegesReihe][0];
    int spalte = siegesReihe[positionInSiegesReihe][1];
    return position[zeile][spalte];
  }

} // end of class TicTacToe
                
/************************ TicTacToeFeld.java *********************/

/**
 * @author philipp gressly freimann. 15. Feb. 2011.
 * CS IL10: Rekursion: Tic Tac Toe
 */

package ch.santis.tic;

import java.awt.Point;
import java.util.ArrayList;

/**
 * Feld: 3x3
 * @author Philipp Gressly (phi AT gressly DOT ch)
 */
public class TicTacToeFeld {
  public static final char PLAYER_X = 'X';
  public static final char PLAYER_O = 'O';
  public static final char NOPLAYER =  0 ;
  
  char [][] feld;
  
  public TicTacToeFeld() {
      feld = new char[3][3];
  }
  
  public char get(int zeile, int spalte) {
      return feld[zeile][spalte];
  }

  public void set(int zeile, int spalte, char player) {
      feld[zeile][spalte] = player;
  }

  public void set(Point move, char spieler) {
     set(move.x, move.y, spieler);  
  }
  
  
  public boolean isFull() {
    int belegt = 0;
    for(int zeile = 0; zeile < 3; zeile ++) {
        for(int spalte = 0; spalte < 3; spalte ++) {
            if(0 != get(zeile, spalte)) {
                belegt = belegt + 1;
            }
        }
    }
    return 9 == belegt; 
  }
  
  final static int [][][] SIEGESREIHEN =
  {
          // Zeilen
          {{0, 0}, {0, 1}, {0, 2}},
          {{1, 0}, {1, 1}, {1, 2}},
          {{2, 0}, {2, 1}, {2, 2}},
          // Spalten
          {{0, 0}, {1, 0}, {2, 0}},
          {{0, 1}, {1, 1}, {2, 1}},
          {{0, 2}, {1, 2}, {2, 2}},
          // Diagonalen
          {{0, 0}, {1, 1}, {2, 2}},
          {{2, 0}, {1, 1}, {0, 2}}
        };
  
  /**
   * isWin() liefert:
   *  - PLAYER_X, falls GewinnPosition für X
   *  - PLAYER_O, falls GewinnPosition für O
   *  - NOPLAYER, sonst
   */
  public char isWin() {
     if(isWin(PLAYER_X)) return PLAYER_X;
     if(isWin(PLAYER_O)) return PLAYER_O;
     return NOPLAYER;
  }
  
  public boolean isWin(char player) {
    for(int[][] siegesReihe : SIEGESREIHEN) {
        if(spielerSiegtAufReihe(siegesReihe, player)) {
            return true;
        }
     }
     return false;
  }
  
  boolean spielerSiegtAufReihe(int[][] reihe, char sp) {
    char p0 = feld[reihe[0][0]][reihe[0][1]];
    char p1 = feld[reihe[1][0]][reihe[1][1]];
    char p2 = feld[reihe[2][0]][reihe[2][1]];
    return p0 == sp && p1 == sp && p2 == sp;
  }
  
  @Override
  public TicTacToeFeld clone() {
    TicTacToeFeld kopie = new TicTacToeFeld();
    for(int zeile = 0; zeile < 3; zeile ++) {
      for (int spalte = 0; spalte < 3; spalte++) {
        kopie.feld[zeile][spalte] = this.feld[zeile][spalte];
      }
    }
    return kopie;
  }
  
  public ArrayList<Point> getAlleZuege() {
    ArrayList<Point> alleZuege;
    alleZuege = new ArrayList<Point>();
    for(int zeile = 0; zeile < 3; zeile ++) {
      for (int spalte = 0; spalte < 3; spalte++) {
        if(NOPLAYER == this.feld[zeile][spalte]){
            alleZuege.add(new Point(zeile, spalte));
        }
      }
    }
    return alleZuege;
  }

  Point randomMove() {
    if(isFull()) return null; // no more moves
    ArrayList<Point> moeglicheZuege;
    moeglicheZuege = getAlleZuege();
    int randomPos = (int) (Math.random()
                            * moeglicheZuege.size());
    return moeglicheZuege.get(randomPos);
  }

  /**
   * Wer ist der gegner?
   */
  char other(char spieler) {
    if(PLAYER_X == spieler) return PLAYER_O;
    if(PLAYER_O == spieler) return PLAYER_X;
    return NOPLAYER;
  }
  
  @Override
  public String toString() {
    String s =  "+-------+";
    for(int zeile = 0; zeile < 3; zeile ++) {
       s = s + "\n|";
       for(int spalte = 0; spalte < 3; spalte ++)
       {
           char v = feld[zeile][spalte];
           if(NOPLAYER != v) {
             s = s + " " + v; 
           } else {
             s = s + "  ";
           }
       }
       s = s + " |";
       if(zeile < 2) {
           s = s + "\n|-------|";
       }
    }
    s = s +  "\n+-------+\n";
    return s;
  }

} // end of class TicTacToeFeld

/*********************** TicTacToeKI.java ***************************/

/**
 * @author philipp gressly freimann. 15. Feb. 2011.
 * CS IL10: Rekursion: Tic Tac Toe
 */

package ch.santis.tic;

import java.awt.Point;
import static ch.santis.tic.TicTacToeFeld.*;

public class TicTacToeKI {
  public Point bestMove(TicTacToeFeld feld, char spieler) {
    int bestWert  = -1;
    Point bestMove = null;
    for(Point move: feld.getAlleZuege()) {
       TicTacToeFeld tempFeld = feld.clone();
       tempFeld.set(move, spieler);
       int aktWert = bewerte(tempFeld, spieler, false);
       if(aktWert > bestWert) {
           bestWert = aktWert;
           bestMove = move;
       }
    }
    if(null == bestMove) {
        return feld.randomMove();
    }
    return bestMove;
  }

/**
 * Bewerte rekursiv ein TicTacToe-Feld.
 * @param feld
 * @param spieler    Für diesen Spieler wird
 *                   bewertet.
 * @param maximieren Es handelt sich um einen
 *                   Maximierungsschritt
 * @return Wert der Postition "feld" für den
 *         Spieler "spieler"
 */
  int bewerte(TicTacToeFeld feld, char spieler, boolean maximieren) {
    if(feld.isWin(PLAYER_X)) {
      if(PLAYER_X == spieler) {
        return  1; 
      } else {
        return -1;
      }
    }
    if(feld.isWin(PLAYER_O)) {
      if(PLAYER_O == spieler) {
        return  1; 
      } else {
        return -1;
      } 
    }
    if(feld.isFull()) {
      return 0; 
    }
    
    // Rekursionsschritt
    int bestWert;
    if(maximieren) { // Maximierungsschritt?
        bestWert = -2;
    } else {
        bestWert =  2;
    }
    for(Point move: feld.getAlleZuege()) {
      TicTacToeFeld tempFld = feld.clone();
      char zieher = maximieren ?
                    spieler    :
                    feld.other(spieler);
      tempFld.set(move, zieher);
      int aktWert = bewerte(tempFld, spieler, !maximieren);
      if(maximieren) {
          if(aktWert > bestWert) {
              bestWert = aktWert;
          }
      } else { // minimieren 
          if(aktWert < bestWert) {
              bestWert = aktWert;
          }
      }
    }
    return bestWert;
  } //bewerte
  
} // end of class TicTacToeKI

/*************************** TicGui.java ****************************/

/**
 * @author philipp gressly freimann. 15. Feb. 2011.
 * CS IL10: Rekursion: Tic Tac Toe
 */ 


package ch.santis.tic.gui;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

// project specific
import ch.santis.tic.TicTacToeFeld;
import static ch.santis.tic.TicTacToeFeld.*;
import ch.santis.tic.TicTacToeKI;

public class TicGui extends JFrame implements ActionListener {
    JButton[][]   buttons  = new JButton[3][3];

    TicTacToeFeld fld      = new TicTacToeFeld();
    TicTacToeKI   ki       = new TicTacToeKI();

    public static void main(String[] args) {
        new TicGui();
    }

    public TicGui(){
        super("TicTacToe");
        JPanel mp = new JPanel();
        makeButtons(mp);
        mp.setLayout(new GridLayout(3, 3));
        add(mp);
        setSize(180, 180);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    void makeButtons(JPanel mp) {
        for (int zeile = 0; zeile < 3; zeile++) {
            for (int spalte = 0; spalte < 3; spalte++) {
                JButton b = new JButton(".");
                buttons[zeile][spalte] = b;
                mp.add(b);
                b.addActionListener(this);
            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JButton src = (JButton) e.getSource();
        movePlayerThenKI(src);
        redrawAll();
    }

    private void movePlayerThenKI(JButton src) {
        for (int zeile = 0; zeile < 3; zeile++) {
            for (int spalte = 0; spalte < 3; spalte++) {
                behandleGeklicktenButton(src, zeile, spalte);
            } // end for spalte
        } // end for zeile
    } // movePlayerThenKI()

  
    private void behandleGeklicktenButton(JButton src, int zeile, int spalte) {
        // war das nicht der geklickte?
        if (buttons[zeile][spalte] != src) {
            return;
        }
        fld.set(zeile, spalte, PLAYER_O);
        if (fld.isWin(PLAYER_O)) {
            JOptionPane.showMessageDialog(this, "Mensch siegt!!");
        }
        if (!fld.isFull()) {
            Point p = ki.bestMove(fld, PLAYER_X);
            fld.set(p, PLAYER_X);
            if (fld.isWin(PLAYER_X)) {
                redrawAll();
                JOptionPane.showMessageDialog(this, "MiniMax siegt!!");
            }

        }

    } // end behandleGeklicktenButton()

    void redrawAll() {
        for (int zeile = 0; zeile < 3; zeile++) {
            for (int spalte = 0; spalte < 3; spalte++) {
                JButton b = buttons[zeile][spalte];
                if (NOPLAYER != fld.get(zeile, spalte)) {
                    b.setText("" + fld.get(zeile, spalte));
                    b.setEnabled(false);
                }
            }
        }
    } // end redrawAll
    
} // end of class TicGui
                

Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

package ch.santis.programmierenlernen.kapitel6;

import java.util.Scanner;

public class Aufgabe_6_15 {
	
	public static void main(String[] args) {
		new Aufgabe_6_15().top();
	}
	
	void top() {
		// Spielfeld (Array) generieren // Zweidimensionaler Array 3x3 (3 Zeilen / 3 Spalten)
		int [][] spielfeld = new int [3][3];
		int runde = 1; // Start bei Runde 1 an
		runde = spielablauf(runde, spielfeld);
		System.out.println("Spieler " + runde + " gewinnt!");
	}
	
	public int spielablauf(int spieler, int [][] spielfeld) {		
		boolean sieg = false;
		while(sieg == false) {
			int player = spielerwechsel(spieler);
			spielereingabe(spielfeld, player);
			spielfeldausgabe(spielfeld);
			sieg = siegesbedingung(spielfeld, player);
			spieler++;
		}
		return spielerwechsel(spieler-1);
	}
	
	public int spielerwechsel(int spieler) {
		if(spieler % 2 == 0) {
			return 2;
		}
			return 1;
	}
	
	public void spielfeldausgabe(int [][] spielfeld) {
		System.out.println("======");
		for(int index = 0; index < spielfeld.length; index++) {
			System.out.println(spielfeld[index][0] + " " + spielfeld[index][1] + " " + spielfeld[index][2]);
		}
		System.out.println("======");
	}
	
	public int spielereingabe(int[][] spielfeld, int spieler) {
		int zeile   = eingabeInt("Zeile:");
		int spalte  = eingabeInt("Spalte:");
		int player  = spielerwechsel(spieler);
		return spielfeld[zeile][spalte] = player;
	}
	
	public boolean siegesbedingung(int spielfeld[][], int spieler) {
		if( dreierreihe(spielfeld, spieler) ) {
			return true;
		}
		return false;
	}
	
	public boolean dreierreihe(int spielfeld[][], int spieler) {
		// Drei in einer Spalte
		if( (int)spielfeld[0][0] == spieler && (int)spielfeld[0][1] == spieler && (int)spielfeld[0][2] == spieler ) {
			return true;
		}
		else if( (int)spielfeld[1][0] == spieler && (int)spielfeld[1][1] == spieler && (int)spielfeld[1][2] == spieler ) {
			return true;
		}
		else if( (int)spielfeld[2][0] == spieler && (int)spielfeld[2][1] == spieler && (int)spielfeld[2][2] == spieler ) {
			return true;
		}
		// Drei in einer Zeile
		else if( (int)spielfeld[0][0] == spieler && (int)spielfeld[1][0] == spieler && (int)spielfeld[2][0] == spieler ) {
			return true;
		}
		else if( (int)spielfeld[0][1] == spieler && (int)spielfeld[1][1] == spieler && (int)spielfeld[2][1] == spieler ) {
			return true;
		}
		else if( (int)spielfeld[0][2] == spieler && (int)spielfeld[1][2] == spieler && (int)spielfeld[2][2] == spieler ) {
			return true;
		}
		// Drei diagonal
		else if( (int)spielfeld[0][0] == spieler && (int)spielfeld[1][1] == spieler && (int)spielfeld[2][2] == spieler ) {
			return true;
		}
		else if( (int)spielfeld[2][0] == spieler && (int)spielfeld[1][1] == spieler && (int)spielfeld[0][2] == spieler ) {
			return true;
		}
		return false;
	}
	
	// Scanner und print
	public void print(String text) {
		System.out.println(text);
	}
	
	Scanner sc = new Scanner(System.in);
	
	// Int einlesen mit ERROR Behandlung wenn Eingabe keine Zahl ist
	public int eingabeInt(String textstring) {
		int eingabe = 0;
		boolean check = false;
		do {
            try {
            	print(textstring);
            	eingabe = sc.nextInt();
            	check = true;
            } catch(Exception e) {
                print("ERROR: Das ist keine Zahl!");
                sc.nextLine();
            }
		} while (!check);
		return eingabe-1; // Eingabe der Tabelle ist von 1 bis 3 (nicht 0 bis 2)
	}

}
                

Lösung von: Jan Roth (Santis Training AG)

function isWinningTicTacToeConstellation(con) {
  let triples = [],
      x;

  // vertikale und horizontale
  for (x = 0; x <= 2; x++) {
    triples.push([con[0][x], con[1][x], con[2][x]]);
    triples.push([con[x][0], con[x][1], con[x][2]]);
  }
  // diagonale
  triples.push([con[1][1], con[0][0], con[2][2]]);
  triples.push([con[1][1], con[2][0], con[0][2]]);

  // tripel prüfen
  for (x = 0; x < triples.length; x++) {
    if (triples[x].indexOf(0) == -1)   // reihen mit 0 werden nicht geprüft

      /* javaScript hat einen sehr schrägen humor, was logische operatoren
      |* betrifft, besonders wenn nullen und einsen im spiel sind.
      |* deswegen der ganze aufwand mit den tripeln.
      \* aber dies hier funktioniert für diesen fall. */
      if (
        triples[x][0] == triples[x][1] &&
        triples[x][0] == triples[x][2]
      ) return true;
  }
  return false;
}

// ausgabe
// beispiele hab ich der (leider anonymen) python-lösung entnommen
console.log(1, isWinningTicTacToeConstellation([
  [0, 1, 0],
  [1, 0, 1],
  [2, 0, 2]
]));

console.log(2, isWinningTicTacToeConstellation([
  [1, 2, 0],
  [0, 1, 2],
  [0, 0, 1]
]));

console.log(3, isWinningTicTacToeConstellation([
  [1, 1, 2],
  [0, 2, 1],
  [2, 0, 0]
]));

console.log(4, isWinningTicTacToeConstellation([
  [0, 0, 2],
  [1, 1, 1],
  [0, 2, 0]
]));

console.log(5, isWinningTicTacToeConstellation([
  [0, 2, 1],
  [0, 2, 1],
  [1, 2, 0]
]));

console.log(6, isWinningTicTacToeConstellation([
  [0, 2, 1],
  [0, 2, 1],
  [0, 0, 1]
]));                                                         // lisalanda@gmx.at
                

Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)

// C++ 14 | VS-2022
#include <iostream>
#include <algorithm>
#include <vector>

int count_players(const std::vector<int>& v) {
    const auto r{ [&v](int n) { return std::count(v.begin(), v.end(), n); } };
    if (r(1) == 3) return 1;
    else if (r(2) == 3) return 2;
    else return 0;
}

template<typename T>
void transform_vector(T& v) {
    T tmp{};
    for (auto i{ 0 }; i < 3; i++) {
        tmp.push_back({ v[0][i], v[1][i], v[2][i] });
        tmp.push_back({ v[i][0], v[i][1], v[i][2] });
    }
    tmp.push_back({ v[0][0], v[1][1], v[2][2] });
    tmp.push_back({ v[0][2], v[1][1], v[2][0] });
    v = tmp;
}

template<typename T>
void winner(const T& v) {
    T tmp{ v };
    transform_vector(tmp);
    for (const auto& t : tmp) {
        auto w{ count_players(t) };
        if (w != 0) {
            std::cout << "Spieler " << w << " hat gewonnen!\n";
            return;
        }
    }
    std::cout << "Kein Spieler hat gewonnen!\n";
}

int main() {
    std::vector<std::vector<int>>ttt{
    {0, 0, 2},
    {1, 1, 1},
    {0, 2, 0} };

    winner(ttt);
}
                

Lösung von: Jens Kelm (@JKooP)

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 1
Schwierigkeit: k.A.
Webcode: imhb-6pb8
Autor: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen