https://pastein.ru/t/RN

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


package kosynka;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.Timer;

public class Logic {

	//признак окончания игры
	public boolean gameEnd; // endGame
	public Image backOfCard; // rubashka
	//массив стопок карт
	private Stack[] stackArray; // stopki
	//признак первой выдачи карт из верхней левой стопки
	private boolean firstDelivery; // pervVidacha
	//номеро стопки захваченной пользователем
	private int selectedStackNum; // nomStopki
	//номер карты в стопке захваченной пользователем
	private int selectedCardNum; // nomKarti
	//Смещение координат курсора мыши
	//относительно координаты карты
	private int dX, dY;
	//координаты карты до начала переноса мышью
	private int oldX, oldY;
	//таймер для эффекта окончания игры
	private Timer timerGameEnd;
	
	
	//конструктор
	public Logic() {
		try {
			backOfCard = ImageIO.read(new File("C:\\cards\\cardback.png"));
		}
		catch (Exception ex) {
			System.out.println("Изображение рубашки не найдено");
		}
		
		//создание массива из 13 элементов
		//каждый элемент массива - это список значения (стопка карт)
		stackArray = new Stack[13];
		
		//заполнение массива в цикле
		for(int i = 0; i<13; i++) {
			stackArray[i] = new Stack();
		}
		
		//таймер для эффекта окончания игры
		//будет запсукаться при успешном завершении игры 
		//скорость работы - 10 раз в секунду
		timerGameEnd = new Timer(100, new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//перебираем все четыре домашние стопки
				for(int i = 2; i<=5; i++) {
					//получаем самую нижнюю карту
					Card card = stackArray[i].getCard(0);
					//нижнюю карту добавляем наверх
					stackArray[i].addCard(card);
					stackArray[i].removeCard(0);
				}
			}
		});
		start();
	}
	
	//проверка окончания игры
	private void checkGameEnd() { // testEndGame
		//проверяем что во всех четырех домашних стопках по 13 карт
		if ( (stackArray[2].size()==13) &&
				(stackArray[3].size()==13) && 
				(stackArray[4].size()==13) && 
				(stackArray[5].size()==13)) 
		{
			//признак окончания игры
			gameEnd = true;
			//запускаем таймер
			timerGameEnd.start();
		}
	}
	
	//автоматическое отркытие верхне й карты
	//в нижних стопках
	private void openCard() { // openKarta
		//Перебираем все нижние стопки
		for(int i=6; i<=12; i++) {
			//ЕСЛИ В СТОПКЕ ЕСТЬ КАРТЫ
			if(stackArray[i].size()>0) {
				//номер последней карты в стопке
				int lastNum = stackArray[i].size()-1;
				//получаем псоледнюю карту
				Card card = stackArray[i].getCard(lastNum);
				//Если карты отображаются рубашкой. то открываем ее
				if(card.isInverted == true) card.isInverted=false;
			}
		}
	}
	
	//При захвате карты мышью
	public void mouseDragged(int mX, int mY) {
		//если стопка выбрана
		if(selectedStackNum>=0) {
			//получаем выбранную картуэ
			Card card = stackArray[selectedStackNum].getCard(selectedCardNum);
			//изменяем координаты карты по курсору мыши
			card.x = mX - dX;
			card.y = mY - dY;
			
			//ограничение области переноса карт
			if (card.x < 0) card.x = 0;	
			if (card.x > 720) card.x = 720;
			if (card.y < 0) card.y = 0;
			if (card.y > 650) card.y = 650;
			
			//все остальные карты в переносимой группе карт
			//размещаем со сдвигом вниз на 20 пикселей
			int y = 20;
			for(int i = selectedCardNum+1; i<stackArray[selectedStackNum].size(); i++) {
				stackArray[selectedStackNum].getCard(i).x = card.x;
				stackArray[selectedStackNum].getCard(i).y = card.y + y;				
				y += 20;
			}
		}
	}
	
	//ри одиночном нажатии левой кнопки мыши
	public void mousePressed(int mX, int mY) {
		//определяем номер стопки
		int num = getPressedStackNum(mX,mY);
		//устанавливаем выбранную карту
		setSelected(num, mX,mY);
	}
	
	//при двойном щелчке левой кнопкой мыши
	public void mouseDoublePressed(int mX, int mY) {
		
	}
	
	//при отпускании левой кнопки мыши
	public void mouseReleased(int mX, int mY) {
		int num = getPressedStackNum(mX, mY);
		if (num == 0) {
			delivery();
		}
	}
	
	//Определение стопки на которую нажали мышью
	private int getPressedStackNum (int mX, int mY) {
		//Если курсор мыши не попал по стопке карт
		//Если стопка не выбрана
		int num = -1;
		
		//если курсор находится в зоне верхних стопок
		if( (mY>= 15) && (mY <= (15+97))) {
			if((mX>=30) && (mX <=(30+72))) num = 0;
			if((mX>=140) && (mX <=(140+72))) num = 1;
			if((mX>=360) && (mX <=(360+72))) num = 2;
			if((mX>=470) && (mX <=(470+72))) num = 3;
			if((mX>=580) && (mX <=(580+72))) num = 4;
			if((mX>=690) && (mX <=(690+72))) num = 5;
		}
		//если курсор находится в зоне нижних стопок
		else if( (mY>=150) && (mY<=700) ) {
			if( (mX>=30) && (mX<= 110*7) ) {
				if(( (mX-30)%110 ) <=72) {
					num = (mX-30)/110;
					num += 6;
				}
			}
		}
		return num;
	}
		
	//Выдача карт из верхней леовй стопки
	private void delivery() { // vidacha()
		if(stackArray[0].size()>0) {
			int num;
			//Если это первая выдача
			if(firstDelivery == true) {
				//поулчаем номер
				num = (int)(Math.random()*stackArray[0].size());
			}
			else {
				num = stackArray[0].size() - 1;
			}
			
			//получаем карту из стопки под номером 0
			Card card = stackArray[0].getCard(num);
			//делаем отображение картинкой
			card.isInverted= false;
			card.x+=110;
			//Увеличаем координату на 110
			stackArray[1].addCard(card);
			stackArray[0].removeCard(num);
		}
		else {
			//вычисляем номер последней картф
			int numLast = stackArray[1].size()-1;
			
			//переносим карты из стопки с номером 1 в стопку 0
			for(int i = numLast; i>=0; i--) {
				Card card = stackArray[1].getCard(i);
				card.isInverted = true;
				//уменьшаем коодинату на 110
				card.x -= 110;
				stackArray[0].addCard(card);
			}
			stackArray[1].clear();
			firstDelivery= false;
		}
	}
	
	///старт игры - новая игры
	public void start() {
		//очищаем все тринадцать списков
		for(int i = 0; i<13; i++) {
			//удаление элементов
			stackArray[i].clear();
		}
		//Производим
		load();	
		distribution();
		gameEnd = false;
		firstDelivery = true;
		selectedStackNum= -1;
		selectedCardNum = -1;
	}
	
	//загрузка изображений колоды
	private void load() {
		for(int i = 0; i <= 52; i++) {
			//в верхнюю левую стопку загружаем карты
			stackArray[0].addCard(new Card("C:\\cards\\k" + (i) + ".png", backOfCard, i));
		}
	}
	
	//метод отрисовки всех стопок карт
	public void drawStack(Graphics gr) {
		//ВЕРХНЯЯ ЛЕВАЯ СТОПКА
		//ЕСЛИ В СТОПКЕ ЕСТЬ КАРТЫ
		if(stackArray[0].size()>0) {
			//поулчаем и рисуем самую верхнюю карту
			stackArray[0].getCard(stackArray[0].size()-1).draw(gr);
		}
		
		//вторая слева верхняя стопка
		if(stackArray[1].size()>1) {
			stackArray[1].getCard(stackArray[1].size()-2 ).draw(gr);
			//получаем и рисуем самую верхнюю карту
			stackArray[1].getCard(stackArray[1].size()-1).draw(gr);
		}
		else if(stackArray[1].size()==1) {
			stackArray[1].getCard(stackArray[1].size()-1).draw(gr);
		}
		
		//ОТРИСОВА ЧЕТЫРЕХ ДОМАШНИХ СТОПОК
		for(int i = 2; i<=5; i++) {
			//если в стопке более одной карты
			if(stackArray[i].size()>1) {
				//полккчаем и рисуем вторую сверху карту
				stackArray[i].getCard(stackArray[i].size()-2).draw(gr);
				//получаем и рисуем самую верхнюю карту
				stackArray[i].getCard(stackArray[i].size()-1).draw(gr);
			}
			else if(stackArray[i].size()==1) {
				stackArray[i].getCard(stackArray[i].size()-1).draw(gr);		
			}
		}
		
		//нижние семь стопок
		for(int i = 6; i<13; i++) {
			//Если в стопке есть карты
			if(stackArray[i].size()>0) {
				//перебираем все карты из стопки
				for(int j=0;j<stackArray[i].size();j++) {
					//если находим выбранную карту
					//то прерываем цикл
					if(stackArray[i].getCard(j).isSelected == true) break;
					stackArray[i].getCard(j).draw(gr);
				}
			}
		}
		
		//переносимыые мышью карты
		//если имеется выбранная стопка
		if(selectedStackNum!=-1) {
			//перебираем карты от выбранной и до конца стопки
			for(int i = selectedCardNum; i<stackArray[selectedStackNum].size(); i++) {
				//рисуем карты
				stackArray[selectedStackNum].getCard(i).draw(gr);
			}
		}
	}
	
	private void distribution() { //razdacha()
		//начальная координата по Х
		int x = 30;
		//перебираем все нижние стопки
		for(int i = 6; i<13; i++) {
			//добавление карт в стопку
			for(int j = 6; j<=i; j++) {
				//получваем номер случайной стопки карты из верхней левой стопки
				int random = (int)(Math.random()*stackArray[0].size());
				//получаем эту карту 
				Card card = stackArray[0].getCard(random);
				//если карта не самая верхняя, то показываем рубашкой вверх
				if(j<i) card.isInverted = true;
				else card.isInverted = false;
				//кордината по Х
				card.x = x;
				//Каждую следующую карту располагаем ниже на 20 пикселей
				card.y = 150+stackArray[i].size()*20;
				//добавляем карту в нижнюю стопку
				stackArray[i].addCard(card);
				//удаляем карту из верхней левой стопки
				stackArray[0].removeCard(random);
			}
			//увеличиваем координату по Х
			x+=110;
		}
	}
	
	//метод для установки выбранной карты
	private void setSelected(int num, int mX, int mY) { // setVibrana
		//если это верхние стопки (1.2.3.4.5)
		if ( (num>=1) && (num <= 5) ) {
			//Если в стопке есть карты
			if(stackArray[num].size()>0) {
				//получаем номер верхней карты
				int lastNum = stackArray[num].size()-1;
				//получаем верхнюю карту
				Card card = stackArray[num].getCard(lastNum);
				//устанавливаем признак выбранной карты
				card.isSelected = true;
				//номер выбранной карты
				selectedCardNum = lastNum;
				//Номер выбранной стопки
				selectedStackNum = num;
				//Смещение курсора мыши
				dX = mX - card.x;
				dY = mY - card.y;
				
				//Запоминаем текущие координаты
				oldX = card.x;
				oldY = card.y;
			}
		}
		//Если нижние семь стопок 
		else if( (num >=6) && (num <=12) ) {
			//если в стопке есть карты
			if(stackArray[num].size()>0) {
				//получаем номер верхней карты
				int lastNum = stackArray[num].size()-1;
				//получаем верхнюю карту
				Card card = stackArray[num].getCard(lastNum);
				int selectedNum = -1; // nomVibrana
				//если выбрана самая верхняя карта
				if (( mY>= card.y) && (mY<=(card.y+97)) ) {
					selectedNum = lastNum;
				}
				
				//Если выбрана НЕ самая вехрняя карта
				else if(mY<card.y) {
					selectedNum = (mY-150)/20;
					if(stackArray[num].getCard(selectedNum).isInverted==true) {
						selectedNum = -1;
					}
				}
				//Если карта выбрана
				if(selectedNum!=-1) {
					//получаем выбранную карту
					Card selectedCard = stackArray[num].getCard(selectedNum);
					//Если карта открыта рубашкой
					if(selectedCard.isInverted == false) {
						//устанавливаем признак выбранной
						selectedCard.isSelected = true;
						//номер выбранной карты
						selectedCardNum = selectedNum;
						selectedStackNum = num;
						//смещеиен курсора мыши
						dX = mX - selectedCard.x;
						dY = mY - selectedCard.y;
						
						oldX = selectedCard.x;
						oldY = selectedCard.y;
					}
				}
			}
		}
	}
}