package com.znv.linkup.core;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.znv.linkup.core.card.Piece;
import com.znv.linkup.core.card.path.LinkInfo;
import com.znv.linkup.core.card.path.TwoCorner;
import com.znv.linkup.core.config.LevelCfg;
import com.znv.linkup.core.map.GameMap;
/**
* 卡片相关的游戏逻辑处理类
*
* @author yzb
*
*/
class GameService {
private Piece[][] pieces;
private LevelCfg levelCfg;
public GameService(LevelCfg levelCfg) {
this.levelCfg = levelCfg;
this.pieces = GameMap.createPieces(levelCfg);
}
/**
* 获取所有卡片信息
*
* @return 所有卡片信息
*/
public Piece[][] getPieces() {
return pieces;
}
/**
* 判断当前是否存在游戏卡片
*
* @return 存在游戏卡片时返回true
*/
public boolean hasPieces() {
for (int i = 0; i < pieces.length; i++) {
for (int j = 0; j < pieces[i].length; j++) {
if (Piece.canSelect(pieces[i][j])) {
return true;
}
}
}
return false;
}
/**
* 根据坐标点查找卡片
*
* @param x
* 横坐标
* @param y
* 纵坐标
* @return 卡片信息
*/
public Piece findPiece(float x, float y) {
int relativeX = (int) x - levelCfg.getBeginImageX();
int relativeY = (int) y - levelCfg.getBeginImageY();
if (relativeX < 0 || relativeY < 0) {
return null;
}
int indexX = getIndex(relativeX, levelCfg.getPieceWidth());
int indexY = getIndex(relativeY, levelCfg.getPieceHeight());
if (indexX < 0 || indexY < 0) {
return null;
}
if (indexY >= pieces.length || indexX >= pieces[0].length) {
return null;
}
return pieces[indexY][indexX];
}
private int getIndex(int relative, int size) {
int index = -1;
if (relative % size == 0) {
index = relative / size - 1;
} else {
index = relative / size;
}
return index;
}
/**
* 重排卡片
*/
public void refresh() {
int index = 0;
// 获取游戏块的值
List<Piece> array = new ArrayList<Piece>();
for (int i = 0; i < pieces.length; i++) {
for (int j = 0; j < pieces[i].length; j++) {
if (Piece.canSelect(pieces[i][j])) {
array.add(pieces[i][j]);
}
}
}
// 随机打乱
Collections.shuffle(array);
// 重新赋值
index = 0;
for (int i = 0; i < pieces.length; i++) {
for (int j = 0; j < pieces[i].length; j++) {
if (Piece.canSelect(pieces[i][j])) {
// 交换
pieces[i][j].exchange(array.get(index++));
}
}
}
}
/**
* 判断两个卡片是否可消除,同时返回连接路径
*
* @param p1
* 卡片1
* @param p2
* 卡片2
* @return 连接路径信息,不可消除时返回null
*/
public LinkInfo link(Piece p1, Piece p2) {
if (p1.equals(p2)) {
return null;
}
if (!p1.isSameImage(p2)) {
return null;
}
if (p2.getIndexX() < p1.getIndexX()) {
return link(p2, p1);
}
LinkInfo linkInfo = null;
linkInfo = zeroCornerConnect(p1, p2);
if (linkInfo != null) {
return linkInfo;
}
linkInfo = oneCornerConnect(p1, p2);
if (linkInfo != null) {
return linkInfo;
}
linkInfo = twoCornerConnect(p1, p2);
if (linkInfo != null) {
return linkInfo;
}
return null;
}
private LinkInfo zeroCornerConnect(Piece p1, Piece p2) {
if (p1.getIndexY() == p2.getIndexY()) {
if (isXConnect(p1, p2)) {
return new LinkInfo(p1, p2);
}
} else if (p1.getIndexX() == p2.getIndexX()) {
if (isYConnect(p1, p2)) {
return new LinkInfo(p1, p2);
}
}
return null;
}
private boolean isXConnect(Piece p1, Piece p2) {
if (p1.getIndexY() != p2.getIndexY()) {
return false;
}
if (p1.getIndexX() == p2.getIndexX()) {
return false;
}
if (p2.getIndexX() < p1.getIndexX()) {
return isXConnect(p2, p1);
}
for (int i = p1.getIndexX() + 1; i < p2.getIndexX(); i++) {
if (Piece.hasImage(pieces[p1.getIndexY()][i])) {
return false;
}
}
return true;
}
private boolean isYConnect(Piece p1, Piece p2) {
if (p1.getIndexX() != p2.getIndexX()) {
return false;
}
if (p1.getIndexY() == p2.getIndexY()) {
return false;
}
if (p2.getIndexY() < p1.getIndexY()) {
return isYConnect(p2, p1);
}
for (int i = p1.getIndexY() + 1; i < p2.getIndexY(); i++) {
if (Piece.hasImage(pieces[i][p1.getIndexX()])) {
return false;
}
}
return true;
}
private LinkInfo oneCornerConnect(Piece p1, Piece p2) {
Piece cornerPiece1 = pieces[p2.getIndexY()][p1.getIndexX()];
Piece cornerPiece2 = pieces[p1.getIndexY()][p2.getIndexX()];
if (isOneCornerConnect(p1, p2, cornerPiece1)) {
return new LinkInfo(p1, cornerPiece1, p2);
}
if (isOneCornerConnect(p1, p2, cornerPiece2)) {
return new LinkInfo(p1, cornerPiece2, p2);
}
return null;
}
private boolean isOneCornerConnect(Piece p1, Piece p2, Piece corner) {
if (Piece.hasImage(corner)) {
return false;
}
if (p2.getIndexX() < p1.getIndexX()) {
return isOneCornerConnect(p2, p1, corner);
}
if (p1.getIndexX() == corner.getIndexX()) {
if (isYConnect(p1, corner) && isXConnect(p2, corner)) {
return true;
}
} else {
if (isXConnect(p1, corner) && isYConnect(p2, corner)) {
return true;
}
}
return false;
}
private LinkInfo twoCornerConnect(Piece p1, Piece p2) {
TwoCorner shortestCorner = null;
TwoCorner twoCorner = null;
twoCorner = chanelConnect(p1, p2, getLeftChanel(p1));
if (twoCorner != null) {
if (twoCorner.isShorterThan(shortestCorner)) {
shortestCorner = twoCorner;
}
}
twoCorner = chanelConnect(p1, p2, getUpChanel(p1));
if (twoCorner != null) {
if (twoCorner.isShorterThan(shortestCorner)) {
shortestCorner = twoCorner;
}
}
twoCorner = chanelConnect(p1, p2, getRightChanel(p1));
if (twoCorner != null) {
if (twoCorner.isShorterThan(shortestCorner)) {
shortestCorner = twoCorner;
}
}
twoCorner = chanelConnect(p1, p2, getDownChanel(p1));
if (twoCorner != null) {
if (twoCorner.isShorterThan(shortestCorner)) {
shortestCorner = twoCorner;
}
}
if (shortestCorner != null) {
return new LinkInfo(p1, shortestCorner.getCornerOne(), shortestCorner.getCornerTwo(), p2);
}
return null;
}
private List<Piece> getLeftChanel(Piece p) {
List<Piece> results = new ArrayList<Piece>();
for (int i = p.getIndexX() - 1; i >= 0; i--) {
if (Piece.hasImage(pieces[p.getIndexY()][i])) {
return results;
}
results.add(pieces[p.getIndexY()][i]);
}
return results;
}
private List<Piece> getRightChanel(Piece p) {
List<Piece> results = new ArrayList<Piece>();
for (int i = p.getIndexX() + 1; i < levelCfg.getXSize(); i++) {
if (Piece.hasImage(pieces[p.getIndexY()][i])) {
return results;
}
results.add(pieces[p.getIndexY()][i]);
}
return results;
}
private List<Piece> getUpChanel(Piece p) {
List<Piece> results = new ArrayList<Piece>();
for (int i = p.getIndexY() - 1; i >= 0; i--) {
if (Piece.hasImage(pieces[i][p.getIndexX()])) {
return results;
}
results.add(pieces[i][p.getIndexX()]);
}
return results;
}
private List<Piece> getDownChanel(Piece p) {
List<Piece> results = new ArrayList<Piece>();
for (int i = p.getIndexY() + 1; i < levelCfg.getYSize(); i++) {
if (Piece.hasImage(pieces[i][p.getIndexX()])) {
return results;
}
results.add(pieces[i][p.getIndexX()]);
}
return results;
}
private TwoCorner chanelConnect(Piece p1, Piece p2, List<Piece> chanelPieces) {
for (Piece p : chanelPieces) {
LinkInfo linkInfo = oneCornerConnect(p, p2);
if (linkInfo != null) {
return new TwoCorner(p1, p, linkInfo.getLinkPieces().get(1), p2);
}
}
return null;
}
}