Надо добавить условие победы в игру

119
16 декабря 2021, 13:40

Это игра с переставлением шариков .Игра состоит из трёх классов : Ball , Hole и MainWindow. Надо добавить условие, при котором игра будет понимать , что игрок победил и выводить сообщение о победе. Первый класс :

    import java.util.ArrayList;
import javax.swing.JOptionPane;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.GC; //Graphics Context
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class MainWindow {
    protected Shell shell;
    public static void main(String[] args) {
        try {
            MainWindow window = new MainWindow();
            JOptionPane
                    .showMessageDialog(null,
                            "Переместите белые шары на место черных, а черные на место белых");
            window.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void open() {
        Display display = Display.getDefault();
        createContents();
        shell.open();
        shell.layout();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }
    void DrawStart(Canvas canvas) {
    }
    ArrayList<Hole> holes = new ArrayList<Hole>();
    private void DrawHole(int D, int height, int index, Hole hole, GC gc) {
        int start = 20;
        int x = index * (D) + index * start + start - 10;
        int ballD = D / 2;
        gc.drawOval(x, 5, D, D);
        if (hole != null) {
            hole.setDiametr(D);
            hole.setX(x + D / 2);
            hole.setY(5 + D / 2);
            if (hole.getBall() != null) {
                gc.setBackground(hole.getBall().getColor());
                gc.fillOval(x + ballD / 2, 5 + D / 2 - ballD / 2, ballD, ballD);
                // System.out.print(hole.getBall().getColor() +"   " + "\n");
            }
        }
    }
    private int GetClickedHoleIndex(int X, int Y) {
        int resultIndex = -1;
        for (Hole hole : holes) {
            int x0 = hole.getX();
            int y0 = hole.getY();
            int r = hole.getDiametr() / 2;
            if (Math.sqrt((x0 - X) * (x0 - X) + (y0 - Y) * (y0 - Y)) <= r) {
                resultIndex = holes.indexOf(hole);
                break;
            }
        }
        return resultIndex;
    }
    int selectedHole;
    void DoMove(int newSelection) {
        if (newSelection != -1 && newSelection != selectedHole) {// нажали в
                                                                    // пустое
                                                                    // место
            if (holes.get(newSelection).getBall() == null) {
                if (Math.abs(newSelection - selectedHole) < 3) {
                    // System.out.println(selectedHole +"       " +newSelection
                    // );
                    holes.get(newSelection).setBall(
                            holes.get(selectedHole).getBall());
                    holes.get(selectedHole).ballMoveOut();
                }
            }
        }
        selectedHole = -1;
    }
    protected void createContents() {
        shell = new Shell();
        shell.setSize(510, 110);
        shell.setText("Сім лунок");
        selectedHole = -1;
        Canvas canvas = new Canvas(shell, SWT.NONE);
        Device device = Display.getCurrent();
        Color black = new Color(device, 0, 0, 0);
        Color white = new Color(device, 255, 255, 255);
        holes.add(new Hole(new Ball(black)));
        holes.add(new Hole(new Ball(black)));
        holes.add(new Hole(new Ball(black)));
        holes.add(new Hole());
        holes.add(new Hole(new Ball(white)));
        holes.add(new Hole(new Ball(white)));
        holes.add(new Hole(new Ball(white)));
        canvas.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent e) {
                int D = canvas.getBounds().width / 10;
                int height = canvas.getBounds().height;
                for (int i = 0; i < 7; i++) {
                    DrawHole(D, height, i, holes.get(i), e.gc);
                }    
            }
        });
        canvas.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseDown(MouseEvent e) {
                // System.out.println(e.x + ";" + e.y);
                if (selectedHole == -1) {
                    selectedHole = GetClickedHoleIndex(e.x, e.y);
                } else {
                    DoMove(GetClickedHoleIndex(e.x, e.y));
                    canvas.redraw();
                }
            }
        });
        canvas.setBounds(0, 0, 501, 64);
    }
}

Второй класс:

    import org.eclipse.swt.graphics.Color;
public class Ball {
    private Color color;
    public Ball(Color color) {
        this.color = color;
    }
    public Color getColor() {
        return color;
    }
}

Третий класс:

    public class Hole {
    private Ball ball;
    private int X, Y, Diametr;

    public Hole(Ball ball) {
        this.setBall(ball);
    }
    public Hole() {
    }
    public void setX(int X) {
        this.X = X;
    }
    public int getX() {
        return this.X;
    }
    public void setY(int Y) {
        this.Y = Y;
    }
    public int getY() {
        return this.Y;
    }
    public void setDiametr(int Diametr) {
        this.Diametr = Diametr;
    }
    public int getDiametr() {
        return this.Diametr;
    }
    public Ball getBall() {
        return ball;
    }
    public void setBall(Ball ball) {
        this.ball = ball;
    }
    public void ballMoveOut() {
        this.ball = null;
    }
}   
Answer 1

Есть несколько замечаний... Во-первых, зачем Вам класс Ball? Единственное его предназначение - хранение перемнной типа Color, мало того, он также инкапсулирован в класс Hole. Зачем Вам класс-посредник? Помните про принцип KISS. Во-вторых, обратите внимание на правила именования переменных и методов. Это может казаться мелочью, но очень влияет на читаемость кода. Сюда же относятся "магические цифры" и т.д. Вы должны понимать, что осмысленное именование переменных и методов добавляет на много больше читаемости коду, чем самый продуманный ооп-подход. И последнее. В вашем коде лично мне не понравился процесс инициализации коллекции типа Hole. Понятное дело, что имея только 7 ячеек и 2 цвета у вас все относительно неплохо, но это вполне ожидаемая ось расширения системы (я имею в виду добавление большего количества ячек и шаров разных цветов). Посему надо иметь более продуманный механизм наполнения указанной коллекции. Для решения последней проблемы предлагаю что-то типа билдера.

Поскольку теперь есть билдер и инициализация коллекции - занятие достаточно тривиальное, то для определения победы предлагаю инициализировать аналогичную коллекцию с победной комбинации, после чего простейшим методом сравнивать их. Этот способ дает очевидное преимущество - гибкий способ определять победную комбинацию.

import com.google.common.base.Objects;
import java.util.List;
import javax.swing.JOptionPane;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.GC; 
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class MainWindow {
    private Shell shell;
    private int selectedHole;
    private List<Hole> holes;
    private List<Hole> win;
    public static void main(String[] args) {
        try {
            MainWindow window = new MainWindow();
            JOptionPane.showMessageDialog(null, "Переместите белые шары на место черных, а черные на место белых");
            window.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void open() {
        Display display = Display.getDefault();
        createContents();
        shell.open();
        shell.layout();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }
    }
    private void drawHole(int d, int index, Hole hole, GC gc) {
        int start = 20;
        int x = index * (d) + index * start + start - 10;
        int ballD = d / 2;
        gc.drawOval(x, 5, d, d);
        if (hole != null) {
            hole.setDiameter(d);
            hole.setX(x + d / 2);
            hole.setY(5 + d / 2);
            if (hole.getColor() != null) {
                gc.setBackground(hole.getColor());
                gc.fillOval(x + ballD / 2, 5 + d / 2 - ballD / 2, ballD, ballD);
            }
        }
    }
    private int getClickedHoleIndex(int X, int Y) {
        int resultIndex = -1;
        for (Hole hole : holes) {
            int x0 = hole.getX();
            int y0 = hole.getY();
            int r = hole.getDiameter() / 2;
            if (Math.sqrt((x0 - X) * (x0 - X) + (y0 - Y) * (y0 - Y)) <= r) {
                resultIndex = holes.indexOf(hole);
                break;
            }
        }
        return resultIndex;
    }
    private void doMove(int newSelection) {
        if (newSelection != -1 && newSelection != selectedHole) {
            if (holes.get(newSelection).getColor() == null) {
                if (Math.abs(newSelection - selectedHole) < 3) {
                    holes.get(newSelection).setColor( holes.get(selectedHole).getColor());
                    holes.get(selectedHole).moveOut();
                }
            }
        }
        selectedHole = -1;
    }
    private void createContents() {
        shell = new Shell();
        shell.setSize(510, 110);
        shell.setText("Сім лунок");
        selectedHole = -1;
        Canvas canvas = new Canvas(shell, SWT.NONE);
        holes = HoleFabric.builder().addBlack(3).addEmpty().addWhite(3).build();
        win = HoleFabric.builder().addWhite(3).addEmpty().addBlack(3).build();
        canvas.addPaintListener((PaintEvent e) -> {
            int d = canvas.getBounds().width / 10;
            int height = canvas.getBounds().height;
            for (int i = 0; i < 7; i++) drawHole(d, i, holes.get(i), e.gc);
        });
        canvas.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseDown(MouseEvent e) {
                if (selectedHole == -1) selectedHole = getClickedHoleIndex(e.x, e.y);
                else {
                    doMove(getClickedHoleIndex(e.x, e.y));
                    canvas.redraw();
                    if (checkWin()) {
                        JOptionPane.showMessageDialog(null, "Победа!");
                        System.exit(0);
                    }
                }
            }
        });
        canvas.setBounds(0, 0, 501, 64);
    }
    private boolean checkWin(){        
        for (int i = 0; i < Math.min(holes.size(), win.size()); i++) {
            if (!Objects.equal(holes.get(i).getColor(), win.get(i).getColor())) return false;            
        }
        return true;
    }
}

import org.eclipse.swt.graphics.Color;
public class Hole {
    private Color color;    
    private int x, y, diameter;
    public Hole(Color color) {
        this.color = color;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getX() {
        return x;
    }
    public void setY(int y) {
        this.y = y;
    }
    public int getY() {
        return y;
    }
    public void setDiameter(int diameter) {
        this.diameter = diameter;
    }
    public int getDiameter() {
        return this.diameter;
    }
    public Color getColor() {
        return color;
    }
    public void setColor(Color color) {
        this.color = color;
    }
    public void moveOut() {
        this.color = null;
    }
}

import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.widgets.Display;
public class HoleFabric {
    final Device device = Display.getCurrent();    
    final List<Hole> list;
    public HoleFabric() {
        this.list = new ArrayList<>();
    }
    public static HoleFabric builder (){
        return new HoleFabric();
    }
    public List<Hole> build (){
        return list;
    }
    public HoleFabric addBlack(int numb) {
        for (int i = 0; i < numb; i++) 
            list.add(new Hole(new Color(device, 0, 0, 0)));        
        return this;
    }
    public HoleFabric addWhite(int numb) {
        for (int i = 0; i < numb; i++) 
            list.add(new Hole(new Color(device, 255, 255, 255)));
        return this;
    }
    public HoleFabric addEmpty() {
        list.add(new Hole(null));
        return this;
    }
}
READ ALSO
не работает css в php совместно с бутстрап

не работает css в php совместно с бутстрап

попробовал в целях обучения сверстать сайт через bootstrapПодключил два стиля, собственный и бутстрап

108
Почему виснет консоль в QT CREATOR на std::cin?

Почему виснет консоль в QT CREATOR на std::cin?

На cppsh работает, но в qt creator почему то нет

172