https://pastein.ru/t/SZ

  скопируйте уникальную ссылку для отправки


import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.*;

//Класс реализующий логику - управление игрой 
public class Game {
    //Изображение рубашки карты
    public Image rubashka;
    //Массив стопок карт
    private Stopka[] stopki;
    //Признак первой выдачи карт их верхней левой стопки
    private boolean pervVidacha;
    //Признак окончания
    public boolean endGame;
    private int nomStopki;
    private int nomKarti;
    //Смещения кооиднаты курсора мыши относительно координаты карты
    private int dx, dy;
    //координаты карты до начала переноса мышью
    private int oldX, oldY;
    //таймер для эффекта окончания игры 
    private Timer tmEndGame;

    public Game() {
        //Загрузка изображения рубашки карты
        try  {
            rubashka = ImageIO.read(new File("/home/atzutz/Desktop/r.jpeg"));
        }
        catch(Exception ex) {}

        //Создание массиа из 13 элементов
        //каждый элемент массива - это список значений, то есть стопка карт
        stopki = new Stopka[13];

        //Для каждого элемента массива цикле, созадем новый объект
        for(int i = 0; i<13; i++) {
            stopki[i] = new Stopka();
        }
        
        tmEndGame = new Timer(100, new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        		//Перебираем четыре домашние стопки
        		for(int i = 2; i <=5; i++) {
        			//Получаем самую нижнюю карту 
        			Karta getKarta = stopki[i].get(0);
        			//Нижнюю карту добавляем наверх
        			stopki[i].add(getKarta);
        			//УДалчем нижнюю карту
        			stopki[i].remove(0);
        		}
        	}
        });
        start();
    }
    
    //Проверка окончания игры 
    private void testEndGame() {
    	//Проврякем что во всех четырх домашних стопках по 13 карт
    	if((stopki[2].size() == 13) &&
    		(stopki[3].size() == 13) &&
    	    (stopki[4].size() == 13) &&
    	    (stopki[5].size() == 13)) {
    		//Признак окончания игры
    		endGame = true;
    		//Запускаем таймер
    		tmEndGame.start();
    	}
    }
    
    
    private void openKarta() {
    	//Перебираем все нижние стопки карт
    	for(int i = 6; i <= 12; i++) {
    		//Если в стопке есть карты 
    		if(stopki[i].size() > 0) {
    			//Номер последней карты в стоппке
    			int nomPosled = stopki[i].size() - 1;
    			//Получаем последнюю карту
    			Karta getKarta = stopki[i].get(nomPosled);
    			//Если карты отображается рубашкой
    			if(getKarta.tipRubashka == true) getKarta.tipRubashka = false;
    		}
    	}
    }
    
    
    //При захвате карты мышью
    public void mouseDragged(int mX, int mY) {
    	//Если стопка выбрана
    	if(nomStopki >= 0) {
    		//Получаем выбранную карту
    		Karta getKarta = stopki[nomStopki].get(nomKarti);
    		//Изменяем координаты карты по курсору мыши
    		getKarta.x = mX - dx;
    		getKarta.y = mY - dy;
    		
    		//Ограничение области переноса
    		if(getKarta.x < 0) getKarta.x = 0;
    		if(getKarta.x > 720) getKarta.x = 720;
    		if(getKarta.y < 0) getKarta.y = 0;
    		if(getKarta.y >650) getKarta.y = 650;
    		
    		//Все остальные карты в переносимой группе карт размещаем со сдвигом вниз на 20 пикселей
    		int y = 20;
    		for(int i = nomKarti + 1; i < stopki[nomStopki].size(); i++) {
    			stopki[nomStopki].get(i).x = getKarta.x;
    			stopki[nomStopki].get(i).y = getKarta.y+y;
    			y += 20;
    		}
    	}
    }

    private void setVibrana(int nom, int mX,int mY) {
        if ((nom>=1) && (nom<=5))
        {
          if (stopki[nom].size()>0)
          {
            int nomPosled= stopki[nom].size()-1;
            Karta getKarta = stopki[nom].get(nomPosled);
            getKarta.vibrana = true;
            nomKarti = nomPosled;
            nomStopki = nom;
            dx = mX-getKarta.x;
            dy = mY-getKarta.y;
            oldX = getKarta.x;
            oldY = getKarta.y;
          }
        }
        else if ((nom>=6) && (nom<=12)) {
            if (stopki[nom].size()>0) {
            	int nomPosled = stopki[nom].size()-1;
            	Karta getKarta = stopki[nom].get(nomPosled);
            	int nomVibrana = -1;
            	if ((mY>=getKarta.y) && (mY<=(getKarta.y+97))) {
            		nomVibrana = nomPosled;
            	}
            	else if (mY < getKarta.y)  {
            		nomVibrana = (mY-130)/20;
            		if (stopki[nom].get(nomVibrana).tipRubashka==true) {
            			nomVibrana = -1;
            		}
            	}
            	if (nomVibrana!=-1) {
            		Karta getKartaVibrana = stopki[nom].get(nomVibrana);
            		if (getKartaVibrana.tipRubashka == false) {
            			getKartaVibrana.vibrana = true;
            			nomKarti = nomVibrana;
            			nomStopki = nom;
            			dx = mX-getKartaVibrana.x;
            			dy = mY-getKartaVibrana.y;
            		  	oldX = getKartaVibrana.x;
            		  	oldY = getKartaVibrana.y;
            	  }
              }
            }
        }
    }
    
    //при одиночном нажатии левой кнопкой мыши
    public void mousePressed(int mX, int mY) {
    	//Определение номера стопки
    	int nom = getNomKolodaPress(mX,mY);
    	//Устаналиваем выбранную карту
    	setVibrana(nom, mX, mY);
    }

    //при ДВОЙНОМ нажатии левой кнопкой мыши
    public void mouseDoublePressed(int mX, int mY) {
    	int nom = getNomKolodaPress(mX,mY);
    	//
    	if ((nom == 1) || ((nom >= 6) && (nom <= 12))) {
    		if (stopki[nom].size() > 0) {
    			int nomPosled = stopki[nom].size() - 1;
    			Karta getKarta = stopki[nom].get(nomPosled);
    			if((mY >= getKarta.y) && (mY <= (getKarta.y + 97))) {
    				for(int i = 2; i <= 5; i++) {
    					//
    					//
    					int rez = - 1;
    					//
    					if(stopki[i].size() == 0) {
    						//
    						if(getKarta.tipKarta == 12) {
    							//
    							rez = i;
     						}
    					}
    					//Если домашняя стопка уже не пустая
    					else {
    						//Получаем номер последней карты в домашней стопке
    						int nomPosled2 = stopki[i].size() - 1;
    						//Получаем саму карту 
    						Karta getKarta2 = stopki[i].get(nomPosled2);
    						//Если эта карта в домашней стопке - туз, а переносим двойку и их масти совпадают
    						if((getKarta2.tipKarta == 12) && (getKarta.mast == getKarta2.mast) && (getKarta.tipKarta == 0)) {
    							//Запоминаем номер домашней стопки
    							rez = i;
    						}
    						
    						//Если эта карта в домашней стопке не туз, а их масти совпадают
    						else if ((getKarta2.tipKarta >= 0) && (getKarta2.tipKarta < 11) && (getKarta.mast == getKarta2.mast)) {
    							//Если переносимая карта на один уровень старше
    							if ((getKarta2.tipKarta + 1 == getKarta.tipKarta)) {
    								//Запоминаем номер домашней стопки
    								rez = i;
    							}
    						}
    					}
    					
    					//Если удалось найти подходящую домашнюю стопку
    					if (rez >= 0) {
    						getKarta.x = (110 * (rez + 1)) + 30;
    						getKarta.y = 15;
    						//Добавляем домашнюю стопку
    						stopki[rez].add(getKarta);
    						//Удаляем из старой стопки
    						stopki[nom].remove(nomPosled);
    						//ПРовреяем конец игры
    						testEndGame();
    						//Прерываем цикл
    						break;
    					}
    				}
    			}
    		}
    	}
    	openKarta();
    }

    //При отпускании левой кнпоки мыши
    public void mouseReleased(int mX, int mY) {
        //Определяем номер стопки
        int nom = getNomKolodaPress(mX,mY);
        
        //
        if(nomStopki != -1) {
        	//Убираем признак у выбранной карты
        	stopki[nomStopki].get(nomKarti).vibrana = false;
        	//
        	if((nom == 01) ||(testPerenos(nomStopki, nom) == false)) {
        		int y = 0;
        		//
        		for(int i = nomKarti; i < stopki[nomStopki].size(); i++) {
        			//Получаем карту 
        			Karta getKarta = stopki[nomStopki].get(i);
        			//Устанавливаем координаты х и у до переноса
        			getKarta.x = oldX;
        			getKarta.y = oldY + y;
        			y += 20;
        		}
        	}
        	
        	//Сброс выбранной карты
        	nomStopki = -1;
        	nomKarti = -1;
        	//отрктиые верхней карты
        	openKarta();
        }
        
        else {
        	//Если ыерхняя левая стопка
        	if(nom == 0 ) {
        		vidacha();
        	}
        }
    }

    private int getNomKolodaPress(int mX, int mY) {
        //Если стопка не выбрана
        int nom = -1;

        if((mY>=15) && (mY<=(15+97))) {
            if((mX>=30) && (mX<=(30+72))) nom = 0;
            if((mX>=140) && (mX<=(140+72))) nom = 1;
            if((mX>=360) && (mX<=(360+72))) nom = 2;
            if((mX>=470) && (mX<=(470+72))) nom = 3;
            if((mX>=580) && (mX<=(580+72))) nom = 4;
            if((mX>=690) && (mX<=(690+72))) nom = 5;
        }
        
        else if((mY >= 130) && (mY <= (700))) {
        	
            if((mX >= 30) && (mX <= 110*7)) {
                if(((mX - 30) % 110) <= 72) {
                    nom = (mX - 30) / 110;
                    nom += 6;
                }
            }
        }
        return nom;
    }

    //выдача карт из верхней левой стопки
    private void vidacha() {
        //еСЛИ В СТОПКЕ есть карты
        if(stopki[0].size()>0) {
            int nom;
            //Если это првая выдача
            if(pervVidacha == true) {
                //Получаем номер случайной карты в стопке
                nom = (int)(Math.random() * stopki[0].size());
            }
            else {
                nom = stopki[0].size() - 1;
            }
            //Получаем карут из стопки с нмоером 0
            Karta getKarta = stopki[0].get(nom);
            //Делаем отображение картинкой
            getKarta.tipRubashka = false;
            //Увеличиваем координату на 110
            //сдвигаем в стпоку правее
            getKarta.x += 110;
            //Добавляем карту в стопку с номером 1
            stopki[1].add(getKarta);
            //Удаляем карту из стопки с номером 0
            stopki[0].remove(nom);
        }

        else //Если карт уже нет
        {
            //Вычиялсем номер последней карты
            int nomPosled = stopki[1].size()-1;

            //Переносим карты из стопки с номером 1 в стопку с номером 0
            for(int i = nomPosled;i>=0; i--) {
                Karta getKarta = stopki[1].get(i);
                //Делем отображение руюашкой
                getKarta.tipRubashka = true;
                //Уменьшаем координату на 110
                //сдвигаем в стопку левее
                getKarta.x -= 110;
                //Добавляем в стопку с номером 0
                stopki[0].add(getKarta);
            }
            stopki[1].clear();
            pervVidacha = false;
        }
    }

    //Старт - новая игра
    public void start() {
        //Очищаем все тринадцать списков
        for(int i = 0; i<13; i++) {
            stopki[i].clear();
        }
        load();
        razdacha();
        //Признак конца игры - false
        endGame = false;
        //Признак первой выдачи - true
        pervVidacha = true;
        nomKarti = -1;
        nomStopki = -1;
    }

    //Загрузка изображений колоды
    private void load() {
        for(int i = 1; i<=52; i++) {
            //В верхнюю левую стопку загружаем карты
            stopki[0].add(new Karta("/home/atzutz/Desktop/card/k" + i +".jpg", rubashka, i));
        }
    }

    //Метод отрисовки всех карт
    public void drawKoloda(Graphics gr) {
        //Верхняя лева стопка
        //Если в стопке есть карты
        if(stopki[0].size() > 0) {
            //Получаем и рисуем самую верхнюю карту
            stopki[0].get(stopki[0].size() - 1).draw(gr);
        }
        //Вторая слева, верхняя левая стопка
        if(stopki[1].size() > 1) {
            //Получаем и рисуем самую верхнюю карту
            stopki[1].get(stopki[1].size() - 2).draw(gr);
            stopki[1].get(stopki[1].size() - 1).draw(gr);
        }
        else if(stopki[1].size() == 1) //Если в стопке одна карта
        {
            //Получаем и рисуем самую верхнюю карту
            stopki[1].get(stopki[1].size()-1).draw(gr);
        }
        for(int i = 2; i<=5; i++) {
            //Если в стопке более одной карты
            if(stopki[i].size() > 1) {
                //Получаем и рисуем вторую сверху карту
                stopki[i].get(stopki[i].size() - 2).draw(gr);
                stopki[i].get(stopki[i].size() - 1).draw(gr);
            }
            else if(stopki[i].size() == 1){
                stopki[i].get(stopki[i].size() - 1).draw(gr);
            }
        }
        
        //Нижние семь стопок
        for(int i = 6; i<13; i++) {
            //Если в стопке есть карты
            if(stopki[i].size()>0) {
                //Переьбираем карты из стопки
                for(int k = 0; k<stopki[i].size(); k++) {
                	//Если находим выбранную карту, то прерываем цикл
                	if(stopki[i].get(k).vibrana == true) break;
                	//Рисуем карты 
                	stopki[i].get(k).draw(gr);
                }
            }
        }
        
        //если имеется выбрананя стопка     
        //Переносим мышью карты
        if(nomStopki != -1) {
        	//Перебираем карты от выбранной и до конца стопки
        	for(int i = nomKarti; i<stopki[nomStopki].size(); i++) {
        		stopki[nomStopki].get(i).draw(gr);
        	}
        }
    }
    
    private void razdacha() {
    	//Начальная координата по Х
    	int x = 30;
    	//Пребеираем все стопки нижние семь стопок
    	for(int i=6; i<13; i++) {
    		for(int k = 6; k <= i; k++) {
    			//Получаем номер случайной карты из верхней левой стопки
    			int md= (int)(Math.random()*stopki[0].size());
    			//ПОлучаем эту карту
    			Karta getKarta = stopki[0].get(md);
    			//Если это карта не самая верхняя, то показываем ее рубашкой
    			if(k<i) getKarta.tipRubashka = true;
    			else getKarta.tipRubashka = false; // Если карта самая верхняя
    			//Координата по х
    			getKarta.x = x;
    			//Каждую соелующую карту располагаем ниже на 20 пикселей
    			getKarta.y = 130 + stopki[i].size() * 20;
    			//Добавляем карту в нижнюю стопку
    			stopki[i].add(getKarta);
    			//Удаляем карту из верхней левой стопки
    			stopki[0].remove(md);
    		}
    		x += 110;    	
    	}
    }
    
    private boolean testPerenos(int nom1, int nom2) {
    	//res of check
    	boolean rez = false;
    	Karta getKarta1 = stopki[nom1].get(nomKarti);
    	Karta getKarta2 = null;
    	//Если есть карты вс стопке
    	if (stopki[nom2].size() > 0) {
    		//получаем верхнюю карту
    		getKarta2 = stopki[nom2].get(stopki[nom2].size() - 1);
    	}
    	
    	//Если четыре домашние стопки
    	if ((nom2 >= 2) && (nom2 <= 5)) {
    		if (nomKarti == (stopki[nom1].size() - 1)) {
    			//Если стопка была пустая
    			if(getKarta2 == null) {
    				//Если переносимая карта туз
    				if(getKarta1.tipKarta == 12) rez = true;
    			}
    			//Если в домашней стопке туз, переносится двойка и масти совпадают
    			else if ((getKarta2.tipKarta == 12) && (getKarta1.mast == getKarta2.mast)
    					&& (getKarta1.tipKarta == 0)) {
    				rez = true;
    			}
    			
    			//Если в домашней стопке не туз, но масти совпадают
    			else if((getKarta2.tipKarta >= 0) && (getKarta2.tipKarta < 11) && (getKarta1.mast == getKarta2.mast)) {
    				//Если переносимая карта по рангу выше на один
    				if((getKarta2.tipKarta + 1 == getKarta1.tipKarta)) {
    					rez = true;
    				}
    			}
    			
    			//Если результат проверки положительный 
    			if(rez == true) {
    				//Переносим карту в домашнюю стопку
    				getKarta1.x = (110 * (nom2 + 1)) + 30;
    				getKarta1.y = 15;
    				stopki[nom2].add(getKarta1);
    				stopki[nom1].remove(nomKarti);
    				testEndGame();
    			}
    		}
    	}
    	
    	//Если перенос в нижние стопки
    	if((nom2 >= 6) && (nom2 <= 12)) {
    		int x = 30 + (nom2 - 6) * 110;
    		int y = 130;
    		
    		//Если нижняя стопка была пустая
    		if(getKarta2 == null) {
    			//Если переносится король
    			if(getKarta1.tipKarta == 11) rez = true;
    		}
    		
	    	else {
	    		//Если верхняя карта открыта
	    		if(getKarta2.tipRubashka == false) {
	    			//Если переносим не на туза
	    			if(getKarta2.tipKarta != 12) {
	    				//Если переносимая карта на один младше или туз переносится на двойку 
	    				if((getKarta2.tipKarta == getKarta1.tipKarta + 1) || ((getKarta2.tipKarta == 0) && (getKarta1.tipKarta == 12))) {
	    					//Если одна мачть черная а дургая красная
	    					if(getKarta2.red_karta != getKarta1.red_karta) {
	    						y = getKarta2.y + 20;
	    						rez = true;
	    					}
	    				}
	    			}
	    		}
	    	}
    		
    		//Если результат проверки положительный 
    		if(rez == true) {
    			//ДОбавляем все карты в новую стопку
    			for(int i = nomKarti; i < stopki[nom1].size(); i++) {
    				Karta getKarta_ = stopki[nom1].get(i);
    				getKarta_.x = x;
    				getKarta_.y = y;
    				stopki[nom2].add(getKarta_);
    				y+=20;
    			}
    			//Удаляем все карты из старой стопки
    			for(int i = stopki[nom1].size() - 1; i >= nomKarti; i--) {
    				stopki[nom1].remove(i);
    			}
    		}
	    }
    	//Возвращаем результат
    	return rez;
    }
}