There is a NullPointerException occurs on the new snakemove field after you performed refactoring. Steps to reproduce: 1. Run Main.java 2. Press key 1/2 to choose a mode. Expected Output: No error Actual Output: The below error message is shown in the console Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "com.cs3343_Group16.greedySnake.service.SnakeMove.move(com.cs3343_Group16.greedySnake.model.Snake)" because "this.snakemove" is null at com.cs3343_Group16.greedySnake.action.UIPainting.actionPerformed(UIPainting.java:94) at java.desktop/javax.swing.Timer.fireActionPerformed(Timer.java:311) at java.desktop/javax.swing.Timer$DoPostEvent.run(Timer.java:243) at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
The bug is due to we forgot to consider the situation where the snakemove field is not yet set. The below modification is done and the game now woks well. //modified actionPerformed in UIPainting.java public void actionPerformed(ActionEvent e) { keyLock = SConstant.SC_UPDATED_KEYBOARD_LOCK; timer.start(); if (!SConstant.SC_GAME_MODE_DEFAULT.equals(game.getMode())) { if (SConstant.SC_GAME_MODE_AI.equals(game.getMode())) { MapStatement.getInstance().initRecord(); game.getSnake().updateMapStatus(); game.getBean().updateMapStatus(); game.getSnake().setDirection(SnakeSelfAutoMove.thinkAndMove(((AISnake) game.getSnake()), game.getBean(), game.getSnake().getDirection())); } setSnakemove(game.getSnake().getDirection()); if(snakemove!=null) { // This if else statement is added snakemove.move(game.getSnake()); } } repaint(); }