Java :: Aufgabe #235 :: Lösung #2

2 Lösungen Lösungen öffentlich
#235

Tic-Tac-Toe GUI

Profi - Java von Gelöschte Person - 01.04.2019 um 21:22 Uhr
Programmiere ein Tic-Tac-Toe Spiele mit GUI.
Moduse die es geben sollte:
1 Spieler vs. Computergegner
1 Spieler vs. 1 Spieler
#2
vote_ok
von fcn200 (220 Punkte) - 26.02.2020 um 15:29 Uhr

Klasse Zeichnen.java

Quellcode ausblenden Java-Code
package TTT;
import java.awt.*;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Zeichnen extends JLabel{
	 int x,y = 10;
	 
	 protected void paintComponent(Graphics g) {
		/*g.drawLine(10, 10, 10, 430);
		g.drawLine(150, 10, 150, 430);
		g.drawLine(280, 10, 280, 430);*/
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
		for(int i=143;i<390;i+=143) {
			g.drawLine(i, y, i, 430);			
		}
		for(int i=150;i<390;i+=140) {
			g.drawLine(10, i, 440, i);
		}
		/* Kreis 0_0 x = 20 y = 20
		 * Kreis 0_1 x = 20 y = 160
		 * Kreis 0_2 x = 20 y = 300
		 * Kreis 1_0 x = 160 y = 20
		 * Kreis 1_1 x = 160 y = 160
		 * Kreis 1_2 x = 160 y = 300
		 * Kreis 2_0 x = 300 y = 20
		 * Kreis 2_1 x = 300 y = 160
		 * Kreis 2_2 x = 300 y = 300
		 */
		
		/*
		 * Kreuz 0_0 x1 = 20  x2 = 20; y1 = 20, x2=140;y2=140;
		 * Kreuz 0_1 x1 = 160  x2 = 140  ; y1 = 20; x2=280; y2=140;
		 * Kreuz 0_2 x1 = 300  x2 = 420 ; y1 = 20; x2=420; y2=20;
		 * 
		 * Kreuz 1_0  20,160,140,280  20,280,140,160
		 * Kreuz 1_1  160,160,280,280  160,280,280,160    
		 * Kreuz 1_2  300,160,420,280  300,280,420,160  
		 *   
		 * Kreuz 2_0  20,300,140,420  20,420,140,300       
		 * Kreuz 2_1  160,300,280,420   160,420,280,300       
		 * Kreuz 2_2  300,300,420,420  300,420,420,300      
		 */
		
		
		// Zeile 1
		if(GUI.state[0]==1) {
			g.drawImage(ImageLoader.imgX, 16, 19, 120,120,null);
		}else if(GUI.state[0]==2){
			g.drawImage(ImageLoader.imgO,16,19,120,120,null);
		}
		if(GUI.state[1]==1) {
			g.drawImage(ImageLoader.imgX, 152, 19, 120,120,null);
		}else if(GUI.state[1]==2){
			g.drawImage(ImageLoader.imgO, 154, 19, 120,120,null);
		}
		if(GUI.state[2]==1) {
			g.drawImage(ImageLoader.imgX, 297, 19, 120,120,null);
		}else if(GUI.state[2]==2){
			g.drawImage(ImageLoader.imgO, 299, 19, 120,120,null);
		}
		
		// Zeile 2
		if(GUI.state[3]==1) {
			g.drawImage(ImageLoader.imgX, 16, 164, 120,120,null);
		}else if(GUI.state[3]==2){
			g.drawImage(ImageLoader.imgO,16,164,120,120,null);
		}
		if(GUI.state[4]==1) {
			g.drawImage(ImageLoader.imgX, 152, 164, 120,120,null);
		}else if(GUI.state[4]==2){
			g.drawImage(ImageLoader.imgO,154,164,120,120,null);
		}
		if(GUI.state[5]==1) {
			g.drawImage(ImageLoader.imgX, 297, 164, 120,120,null);
		}else if(GUI.state[5]==2){
			g.drawImage(ImageLoader.imgO,299,164,120,120,null);
		}
		
		// Zeile 3
		if(GUI.state[6]==1) {
			g.drawImage(ImageLoader.imgX, 16, 309, 120,120,null);
		}else if(GUI.state[6]==2){
			g.drawImage(ImageLoader.imgO,16,309,120,120,null);
		}
		if(GUI.state[7]==1) {
			g.drawImage(ImageLoader.imgX, 152, 309, 120,120,null);
		}else if(GUI.state[7]==2){
			g.drawImage(ImageLoader.imgO,154,311,120,120,null);
		}
		if(GUI.state[8]==1) {
			g.drawImage(ImageLoader.imgX, 297, 309, 120,120,null);
		}else if(GUI.state[8]==2){
			g.drawImage(ImageLoader.imgO,299,311,120,120,null);
		}
		
		int count_places = 0;
		for(int i=0;i<=8;i++) {
			if(GUI.state[i]!=0) {
				count_places++;
			}
		}
		
		if(GUI.player==0 && GUI.winner==0 && count_places<9) {
			g.setFont(new Font("Tahoma",Font.PLAIN,20));
			g.drawString("Spieler: X ist am Zug",463,102);
		}else if(GUI.player==1 && GUI.winner==0 && count_places<9) {
			g.setFont(new Font("Tahoma",Font.PLAIN,20));
			g.drawString("Spieler: Computer ist am Zug",463,102);
		}
		if(GUI.winner==1) {
			g.setFont(new Font("Tahoma",Font.PLAIN,20));
			g.drawString("Spieler: X hat gewonnen",463,102);
			
		}else if(GUI.winner==2) {
			g.setFont(new Font("Tahoma",Font.PLAIN,20));
			g.drawString("Spieler: Computer hat gewonnen",463,102);
			
		}
		
			
			if(GUI.winner==0&&count_places==9) {
				g.setFont(new Font("Tahoma",Font.PLAIN,20));
				g.drawString("Spiel vorbei, kein Gewinner",463,102);
			}
		
		
		if(GUI.player==1) {
			
			Spiellogik.AIPlayer();
		}
		Spiellogik.checkWon();
		revalidate();
		repaint();
		
	}
	
	
}


Klasse ActionHandler.java
Quellcode ausblenden Java-Code
package TTT;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ActionHandler implements ActionListener {

	

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		int index = -1;
		//Find Button ID
		for(int i=0;i<GUI.btn.length;i++) {
			if(e.getSource()==GUI.btn[i]) {
				index = i;
			}
		}
		
		if(GUI.state[index] == 0 && GUI.player==0 && GUI.winner == 0) {
			GUI.state[index] = 1;
			GUI.player = 1;
		}else if(GUI.state[index] == 0 && GUI.player==1 && GUI.winner == 0) {
			GUI.state[index] = 2;
			GUI.player = 0;
			
		}
		
		
	}

}


Klasse ButtonPlacement.java

Quellcode ausblenden Java-Code
package TTT;

public class ButtonPlacement {
	
	public static void place() {
		// Reihe 1 
		GUI.btn[0].setBounds(10,10,130,135);
		GUI.btn[1].setBounds(150,11,130,135);
		GUI.btn[2].setBounds(290,11,130,135);
		
		// Reihe 2
		GUI.btn[3].setBounds(10,157,130,126);
		GUI.btn[4].setBounds(150,157,130,126);
		GUI.btn[5].setBounds(290,157,130,126);
		
		// Reihe 3
		GUI.btn[6].setBounds(10,294,130,135);
		GUI.btn[7].setBounds(150,294,130,135);
		GUI.btn[8].setBounds(290,294,130,135);
	}

}


Klasse ImageLoader.java

Quellcode ausblenden Java-Code
package TTT;

import java.awt.Image;
import java.io.File;

import javax.imageio.ImageIO;

public class ImageLoader {
	static Image imgX, imgO;
	public ImageLoader() {
		try {
			imgX = ImageIO.read(new File("src/x.png"));
			imgO = ImageIO.read(new File("src/o.png"));
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

}


Klasse GUI.java

Quellcode ausblenden Java-Code
package TTT;
import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.border.LineBorder;

public class GUI extends JFrame {

	ButtonPlacement bp;
	private JPanel contentPane;
	static JLabel lbl_Spieler;
	Zeichnen zeichnen;
	JFrame jf;
	static JButton btn[] = new JButton[9];
	static int state[] = {0,0,0,0,0,0,0,0,0};
	static int player = 0;
	static int winner = 0;
	private JButton btn_reset;
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					GUI gui = new GUI();
					new ImageLoader();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public GUI() {
		
		jf = new JFrame();
		jf.setSize(800,550);
		jf.setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		jf.setResizable(false);
		jf.setTitle("Tic Tac Toe");
		
		
		
		for(int i=0;i<btn.length;i++) {
			btn[i] = new JButton();
			btn[i].setBounds(20,20,140,140);
			btn[i].setVisible(true);
			btn[i].addActionListener(new ActionHandler());
			btn[i].setFocusPainted(false);
			btn[i].setContentAreaFilled(false);
			btn[i].setBorder(null);
			jf.getContentPane().add(btn[i]);
		}
		ButtonPlacement.place();
		
		zeichnen = new Zeichnen();
		zeichnen.setBounds(0, 0, 794, 521);
		
		zeichnen.setVisible(true);
		jf.getContentPane().setLayout(null);
		jf.getContentPane().add(zeichnen);
		
		JLabel lblNewLabel = new JLabel("");
		lblNewLabel.setBackground(Color.WHITE);
		lblNewLabel.setOpaque(true);
		lblNewLabel.setBounds(463, 82, 320, 28);
		jf.getContentPane().add(lblNewLabel);
		
		btn_reset = new JButton("Reset");
		btn_reset.setBounds(550, 141, 218, 23);
		jf.getContentPane().add(btn_reset);
		btn_reset.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				Spiellogik.reset();
			}
		});
		jf.setLocationByPlatform(true);
		
		
		jf.setVisible(true);
	}
}


Klasse Spiellogik.java

Quellcode ausblenden Java-Code
package TTT;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;



public class Spiellogik {
	static int marken_0,marken_1,marken_2 = 0;
	static boolean block_hor_ver = false;
	static boolean block_diagonal = false;
	static boolean win_hor_ver = false;
	static boolean win_diagonal = false;
	static boolean check_win = false;
	static boolean makeWinTurn = false;
	public static void checkWon() {
		
		    // Zeile 1 horizontal
			if(GUI.state[0]==1 && GUI.state[1]==1 && GUI.state[2]==1) {
				GUI.winner = 1;
			}else if(GUI.state[0]==2 && GUI.state[1]==2 && GUI.state[2]==2) {
				GUI.winner = 2;
			}
			
			// Zeile 2 horizontal			
			if(GUI.state[3]==1 && GUI.state[4]==1 && GUI.state[5]==1) {
				GUI.winner = 1;
			}else if(GUI.state[3]==2 && GUI.state[4]==2 && GUI.state[5]==2) {
				GUI.winner = 2;
			}
			
			// Zeile 3 horizontal			
			if(GUI.state[6]==1 && GUI.state[7]==1 && GUI.state[8]==1) {
					GUI.winner = 1;
			}else if(GUI.state[6]==2 && GUI.state[7]==2 && GUI.state[8]==2) {
					GUI.winner = 2;
			}	
			
			// Zeile 1 vertical			
			if(GUI.state[0]==1 && GUI.state[3]==1 && GUI.state[6]==1) {
					GUI.winner = 1;
			}else if(GUI.state[0]==2 && GUI.state[3]==2 && GUI.state[6]==2) {
					GUI.winner = 2;
			}
			
			// Zeile 2 vertical			
			if(GUI.state[1]==1 && GUI.state[4]==1 && GUI.state[7]==1) {
					GUI.winner = 1;
			}else if(GUI.state[1]==2 && GUI.state[4]==2 && GUI.state[7]==2) {
					GUI.winner = 2;
			}
			// Zeile 3 vertical			
			if(GUI.state[2]==1 && GUI.state[5]==1 && GUI.state[8]==1) {
					GUI.winner = 1;
			}else if(GUI.state[2]==2 && GUI.state[5]==2 && GUI.state[8]==2) {
					GUI.winner = 2;
			}
			
			// Diagonal		
			if(GUI.state[0]==1 && GUI.state[4]==1 && GUI.state[8]==1) {
					GUI.winner = 1;
			}else if(GUI.state[0]==2 && GUI.state[4]==2 && GUI.state[8]==2) {
					GUI.winner = 2;
			}
			if(GUI.state[2]==1 && GUI.state[4]==1 && GUI.state[6]==1) {
					GUI.winner = 1;
			}else if(GUI.state[2]==2 && GUI.state[4]==2 && GUI.state[6]==2) {
					GUI.winner = 2;
			}	
			
			
	}
	public static void reset() {
		for(int i=0;i<GUI.state.length;i++) {
			GUI.state[i] = 0;
		}
		GUI.player = 0;
		GUI.winner = 0;
	}
	
	public static void AIPlayer() {
		
		String Zeile_0 = GUI.state[0]+""+GUI.state[1]+""+GUI.state[2];
		String Zeile_1 = GUI.state[3]+""+GUI.state[4]+""+GUI.state[5];
 		String Zeile_2 = GUI.state[6]+""+GUI.state[7]+""+GUI.state[8];
 		String Diagonal_1 = GUI.state[0]+""+GUI.state[4]+""+GUI.state[8];
 		String Diagonal_2 = GUI.state[2]+""+GUI.state[4]+""+GUI.state[6];
		
 		block_hor_ver = checkBlockHorizontalVertical(Zeile_0, Zeile_1, Zeile_2);
 		// Prüfe ob Blocken diagonal möglich
 		block_diagonal = checkBlockDiagonal(Diagonal_1, Diagonal_2);
 		// Prüfe günstigen Zug der zum Sieg führt
		win_hor_ver = checkWinHorizontalVertical(Zeile_0, Zeile_1, Zeile_2);
		win_diagonal = checkWinDiagonal(Diagonal_1, Diagonal_2);
 		
		
		if(win_hor_ver || win_diagonal) {
			block_hor_ver =false;
			block_diagonal =false;
		
			
			if(win_hor_ver && win_diagonal ) {
				Random r2 = new Random();
				int rand_nmb = r2.nextInt((1-0)+1)+0;
				if(rand_nmb==0) {
					playHorVerWinTurn(Zeile_0,Zeile_1,Zeile_2);
				}else if(rand_nmb==1) {
					playDiagWinTurn(Diagonal_1,Diagonal_2);
				}
			}else if(win_hor_ver&&!win_diagonal) {
				playHorVerWinTurn(Zeile_0,Zeile_1,Zeile_2);
			}else if(!win_hor_ver&&win_diagonal) {
				playDiagWinTurn(Diagonal_1,Diagonal_2);
			}
			
		}
 		
		if(block_hor_ver&& !block_diagonal) {					
			blockHorVer(Zeile_0,Zeile_1,Zeile_2);		
		}		

		if(!block_hor_ver && block_diagonal){
			blockDiagonal(Diagonal_1, Diagonal_2);		
		}
		//TODO beide blocken = true
		if(block_hor_ver && block_diagonal) {
			Random r3 = new Random();
			int rand_number = r3.nextInt((1-0)+1)+0;
			switch(rand_number) {
				case 0: blockHorVer(Zeile_0, Zeile_1, Zeile_2);break;
				case 1: blockDiagonal(Diagonal_1, Diagonal_2);break;
			}
		}
		
		
		
		
	
		
		
		
		if(!makeWinTurn&&!block_hor_ver && !block_diagonal && !win_hor_ver && !win_diagonal&& GUI.winner == 0) {			
			int index = generateTurn();
			if(GUI.state[index]==1 || GUI.state[index]==2) {
				generateTurn();
			}else {
				GUI.state[index] = 2;
				GUI.player = 0;	
			}
		}				
		
		
	}
		
	
	private static void playDiagWinTurn(String Diagonal_1,String Diagonal_2) {
		if(Diagonal_1.equals("202")||Diagonal_1.equals("220")||Diagonal_1.equals("022")) {
			
			if(GUI.state[0]!=2) {
				GUI.state[0]=2;					 
			}else if(GUI.state[4]!=2) {
				GUI.state[4]=2;
			}else if(GUI.state[8]!=2) {
				GUI.state[8]=2;
			}					
				GUI.player = 0;			
	    }
	
		
		if(Diagonal_2.equals("202")||Diagonal_2.equals("220")||Diagonal_2.equals("022")) {
					
			if(GUI.state[6]!=2) {
				GUI.state[6]=2;					 
			}else if(GUI.state[4]!=2) {
				GUI.state[4]=2;
			}else if(GUI.state[2]!=2) {
				GUI.state[2]=2;
			}					
				GUI.player = 0;			
		}
		
	}
	private static void playHorVerWinTurn(String Zeile_0,String Zeile_1, String Zeile_2) {
		
		if(Zeile_0.equals("202")||Zeile_0.equals("220")||Zeile_0.equals("022")) {
			System.out.println(Zeile_0);
			if(GUI.state[0]!=2) {
				GUI.state[0]=2;					 
			}else if(GUI.state[1]!=2) {
				GUI.state[1]=2;
			}else if(GUI.state[2]!=2) {
				GUI.state[2]=2;
			}
			GUI.player = 0;		
		}
		
		
		if(Zeile_1.equals("202")||Zeile_1.equals("220")||Zeile_1.equals("022")) {
			
			if(GUI.state[3]!=2) {
				GUI.state[3]=2;					 
			}else if(GUI.state[4]!=2) {
				GUI.state[4]=2;
			}else if(GUI.state[5]!=2) {
				GUI.state[5]=2;
			}
		
		GUI.player = 0;			
		}
		
		if(Zeile_2.equals("202")||Zeile_2.equals("220")||Zeile_2.equals("022")) {
					
				if(GUI.state[6]!=2) {
					GUI.state[6]=2;					 
				}else if(GUI.state[7]!=2) {
					GUI.state[7]=2;
				}else if(GUI.state[8]!=2) {
					GUI.state[8]=2;
				}					
					GUI.player = 0;			
		}		
	}
	private static int generateTurn() {
		//Zufällige Position erzeugen
		Random r = new Random();
		int randomNumber = r.nextInt((8-0)+1)+0;		
		return randomNumber;
	}
	
	public static boolean checkBlockHorizontalVertical(String Zeile_0,String Zeile_1, String Zeile_2) {
		
		if(Zeile_0.equals("101")||Zeile_0.equals("110")||Zeile_0.equals("011")
		   ||Zeile_1.equals("101")||Zeile_1.equals("110")||Zeile_1.equals("011")
		   ||Zeile_2.equals("101")||Zeile_2.equals("110")||Zeile_2.equals("011")) {
			block_hor_ver=true;
		}else {
			block_hor_ver=false; 			
		}
		return block_hor_ver;
	}
	
	public static boolean checkBlockDiagonal(String Diagonal_1, String Diagonal_2) {
		if(Diagonal_1.equals("101")||Diagonal_1.equals("110")||Diagonal_1.equals("011")
		   ||Diagonal_2.equals("101")||Diagonal_2.equals("110")||Diagonal_2.equals("011")) {
			block_diagonal = true;
		}else {
			block_diagonal = false;
		}
		return block_diagonal;
	}
	
	public static boolean checkWinHorizontalVertical(String Zeile_0,String Zeile_1, String Zeile_2) {
		if(Zeile_0.equals("202")||Zeile_0.equals("220")||Zeile_0.equals("022")
		  ||Zeile_1.equals("202")||Zeile_1.equals("220")||Zeile_1.equals("022")
		  ||Zeile_2.equals("202")||Zeile_2.equals("220")||Zeile_2.equals("022")) {
		    win_hor_ver=true;
		}else {
			win_hor_ver=false; 			
		}
		return win_hor_ver;
	}
	
	public static boolean checkWinDiagonal(String Diagonal_1,String Diagonal_2) {
		if(Diagonal_1.equals("202")||Diagonal_1.equals("220")||Diagonal_1.equals("022")
		  ||Diagonal_2.equals("1202")||Diagonal_2.equals("220")||Diagonal_2.equals("022")) {
			win_diagonal = true;
		}else {
			win_diagonal = false;
		}
		return win_diagonal;
	}
	
	public static void blockHorVer(String Zeile_0,String Zeile_1,String Zeile_2) {
		// Block Player in Zeile 0
					if(Zeile_0.equals("101")||Zeile_0.equals("110")||Zeile_0.equals("011")) {
						System.out.println(Zeile_0);
						if(GUI.state[0]!=1) {
							GUI.state[0]=2;					 
						}else if(GUI.state[1]!=1) {
							GUI.state[1]=2;
						}else if(GUI.state[2]!=1) {
							GUI.state[2]=2;
						}
						GUI.player = 0;		
					}
				
					// Block Player in Zeile 1
					if(Zeile_1.equals("101")||Zeile_1.equals("110")||Zeile_1.equals("011")) {
						
							if(GUI.state[3]!=1) {
								GUI.state[3]=2;					 
							}else if(GUI.state[4]!=1) {
								GUI.state[4]=2;
							}else if(GUI.state[5]!=1) {
								GUI.state[5]=2;
							}
						
						GUI.player = 0;			
					}
					// Block Player in Zeile 2
					if(Zeile_2.equals("101")||Zeile_2.equals("110")||Zeile_2.equals("011")) {
								
							if(GUI.state[6]!=1) {
								GUI.state[6]=2;					 
							}else if(GUI.state[7]!=1) {
								GUI.state[7]=2;
							}else if(GUI.state[8]!=1) {
								GUI.state[8]=2;
							}					
								GUI.player = 0;			
					}
	}
	
	public static void blockDiagonal(String Diagonal_1,String Diagonal_2) {
		// Wenn Horizontal bzw. Vertical nichts zu blocken, dann prüfe ob blocke diagonal möglich
					block_diagonal = checkBlockDiagonal(Diagonal_1, Diagonal_2);				
					
		//Block Player in Diagonale 1
		if(Diagonal_1.equals("101")||Diagonal_1.equals("110")||Diagonal_1.equals("011")) {
					
			if(GUI.state[0]!=1) {
				GUI.state[0]=2;					 
			}else if(GUI.state[4]!=1) {
				GUI.state[4]=2;
			}else if(GUI.state[8]!=1) {
				GUI.state[8]=2;
			}					
				GUI.player = 0;			
		    }
					
		//Block Player in Diagonale 2
		if(Diagonal_2.equals("101")||Diagonal_2.equals("110")||Diagonal_2.equals("011")) {
									
			if(GUI.state[6]!=1) {
				GUI.state[6]=2;					 
			}else if(GUI.state[4]!=1) {
				GUI.state[4]=2;
			}else if(GUI.state[2]!=1) {
				GUI.state[2]=2;
			}					
				GUI.player = 0;			
			}
	}
}

Kommentare:

Für diese Lösung gibt es noch keinen Kommentar

Bitte melden Sie sich an um eine Kommentar zu schreiben.
Kommentar schreiben
2113242

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.